C# Palindrome Test [duplicate] - c#

This question already has answers here:
Check if a string is a palindrome
(33 answers)
Closed 3 years ago.
I need to create a IsPalindrome function where it will determine if a provided string is a palindrome. Alphanumeric chars will be considered when evaluating whether or not the string is a palindrome. With this said, I am having trouble trying to disreguard the spaces and the Caps. Here is what my function looks like now.
If this makes a difference: After this function is done I will then have to have parse a JSON file and have each element in the "strings" array, into the IsPalindrome function.
Any tips?
private static bool IsPalindrome(string value)
{
var min = 0;
var max = value.Length - 1;
while (true)
{
if (min > max)
return true;
var a = value[min];
var b = value[max];
if (if (char.ToLower(a) == char.ToLower(b))
{
return true;
}
else {
return false;
}
min++;
max--;
}

The way I'd do this is to turn the string into an array of characters, skipping non-letter characters, and making all the characters lowercase. Then, I'd use an index to check if the first half of the array is equal to the last. Something like this:
public static bool IsPalindrome(string value)
{
char[] forwards = (from c in value.ToLower().ToCharArray() where char.IsLetter(c) select c).ToArray();
int middle = (forwards.Length / 2) + 1;
for (int i = 0; i < middle; i++)
if (forwards[i] != forwards[forwards.Length - 1 - i])
return false;
return true;
}
That first line uses LINQ to make the array, so you need a using System.Linq;

Related

Check if a word exists in another string in c# without using any inbuilt function

string sentence = "This is a goodday";
string word = "good";
I know this can be done with .Contains() method. I was asked in an interview how to do it without contains method.
how to do it in english.
pick the first letter of word.
walk down sentence a character at a time till you find that letter
now look at the next letters in sentence to see if they are the rest of that word
yes - done
no - keep going
the thing to use is that word[x] is the x-1th character of word, so you just need 2 indexes and a loop or 2
Q: Check if a word exists in another string in c# without using any inbuilt function
A: Tricky
It depends on how detailed that "any inbuilt function" really is.
In general the algorithm is simple:
Loop through the string you're searching in
for each position, see if you've found the word
you do this by looping through all the characters in what we're looking for
and compare each character from the first string with one from the second
if they all matched, we've found a match
but then ... "without using any inbuilt function".
I assume this would mean, do not use the obvious ones, such as Contains, IndexOf, a regular expression, all those things.
But taken to the extreme, does that mean I cannot even know how long the strings are? Is s.Length a built-in function? And thus not allowed?
public bool Contains(string value, string whatWereLookingFor)
{
return IndexOf(value, whatWereLookingFor) >= 0;
}
public int Length(string s)
{
int result = 0;
for (int i = 0; i <= 2147483647; i++)
{
try
{
char c = s[i];
}
catch (IndexOutOfRangeException)
{
break;
}
result = i + 1;
}
return result;
}
public int IndexOf(string value, string whatWereLookingFor)
{
int iMax = Length(value);
int whatMax = Length(whatWereLookingFor);
for (int i = 0; i <= iMax - whatMax; i++)
{
bool isMatch = true;
for (int j = 0; j < whatMax; j++)
{
if (value[i + j] != whatWereLookingFor[j])
{
isMatch = false;
break;
}
}
if (isMatch)
return i;
}
return -1;
}
How about using a for loop?
Loop through the sentence checking for the first character of the work. Once you find that check for the next character of the word until you find the whole word (done - word exists in sentence) or a different character so you start again looking for the first character of the word until you run out of characters.
As the comments say, it would have been nicer to let us know what you answered.
try this:
static bool checkString(string inputString="",string word="")
{
bool returV=false;
if(inputString =="" || word=="")
return false;
int intexcS=0;
Dictionary<int,string> d = new Dictionary<int, string>();
foreach (char cW in word)
{
foreach (char cS in inputString)
{
if(cW==cS){
if(!d.ContainsKey(intexcS) && d.Count<word.Length){
d.Add(intexcS,cW.ToString());
}
}
intexcS++;
}
intexcS=0;
}
int i=0;
foreach(var iitem in d) { if(iitem.Value!=word[i].ToString()) returV=false; else returV=true; i++; }
return returV;
}

How to check if a string ends with a number, without regex? [duplicate]

This question already has answers here:
Extract number at end of string in C#
(9 answers)
Regex for number at the end of string?
(5 answers)
Closed 3 years ago.
I need to check if the last character of a string ends with an int. I would like to avoid using a regular expression, because I think it is very hard, but if there is no smoother way of doing it, I will try it.
I basically tried something that looks like this:
text.EndsWith(INTEGER)]
Boolean result = char.IsDigit(text[text.Length - 1]);
using linq Last method and Isdigit function
bool isDigit = Char.IsDigit(("one1").Last());
Isolate the last character and try parse it to integer:
private static bool IsStringEndsWithDigit(string str)
{
if (String.IsNullOrEmpty(str))
{
return false;
// or throw an exception
// throw new Exception("string can not be empty");
}
string last = str.Substring(str.Length - 1, 1);
int num;
var isNum = int.TryParse(last, out num);
return isNum;
}
var lastChar = text.Last();
var endsWithNum = lastChar >= '0' && lastChar <= '9';
string s = "hello world0";
int len = s.Length;
List<char> digits = new List<char>(){'0','1','2','3','4','5','6','7','8','9'};
if (digits.Contains(s[len - 1]))
{
Console.WriteLine("last character is digits");
}

Why my string.Remove() is not working as expected? [duplicate]

This question already has an answer here:
string.Remove doesnt work [duplicate]
(1 answer)
Closed 6 years ago.
I am trying to solve this problem of finding if two words are anagrams of one another (if we rearrange a string, it matches second string).
Based on Remove single character from a string I built my own function:
public class AreAnagrams
{
public static bool AreStringsAnagrams(string FirstString, string SecondString)
{
if (FirstString == null || b == null)
return false;
if (FirstString.Length != SecondString.Length)
return false;
for (int i = 0; i < SecondString.Length; i++)
{
if (FirstString.IndexOf(SecondString[i]) == -1)
return false;
else
FirstString.Remove(FirstString.IndexOf(SecondString[i]), 1); // Here it does not modify FirstString, even if I put 2nd parameter as 1
}
if (FirstString.Length > 0)
return false;
return true;
}
public static void Main(string[] args)
{
Console.WriteLine(AreStringsAnagrams("neural", "unreal"));
}
}
On my watch I see FirstString still as is. What is the problem? Please and thank you
Assign the result to FirstString
FirstString = FirstString.Remove(FirstString.IndexOf(SecondString[i]), 1);

C# method/function that returns true or false if a character appears in a string repeatedly

I need to write a method/function using C# that accepts two parameters: one string and one character. The function should return true if for every instance of the character in the string, there is another instance of the character immediately to the left or right. In other words, the function should return true only if the character appears in the string only as a pair. I can't seem to figure it out.
Examples:
Manipulation("abcdeefghi", 'e') -> true
Manipulation("abcdeeefghi", 'e') -> false
Currently I have:
public bool Manipulation(string strParam, char[] charParam)
{
if (strParam.Contains(charParam))
{
return true;
}
return false;
}
I already know this doesn't work but I was trying to at least get a return of true if I could find it at least once in the string.
Well one way of looking at it would be traversing the string once, just checking if a run of your char appears: Note that this answer requires the char to appear exactly twice, for example:
IsPairOccurence("abcdeefghi", 'e') -> true
IsPairOccurence("abcdeeefghi", 'e') -> false
Checking if it appears at least twice is easier, as shown by #aditya's answer.
private bool IsPairOccurence(string s, char c) {
int occurence = 0; // the number of consecutive occurences
for (int i = 0; i < s.Length; i++) {
if (s[i] == c) { // If you encounter the character
occurrence++; // Increase the counter
} else { // If another character occurs
if (occurence == 2) {
// Check if the number of consecutive occurences was exactly 2
return true;
}
// If not, reset the counter
occurence = 0;
}
}
return occurence == 2;
}
This answer is surprisingly easy to generalise for any case, e.g. if you want to count exactly occurrences of 3 consecutive or 24 consecutive chars. You can even generalise it for n consecutive characters:
private bool DoesOccurNTimes(string s, char c, int n) {
int occurence = 0; // the number of consecutive occurences
for (int i = 0; i < s.Length; i++) {
if (s[i] == c) { // If you encounter the character
occurrence++; // Increase the counter
} else { // If another character occurs
if (occurence == n) {
// Check if the number of consecutive occurences was exactly n
return true;
}
// If not, reset the counter
occurence = 0;
}
}
// Check for the end of the string
return occurence == n;
}
Now IsPairOccurence(s, c) is simply DoesOccurNTimes(s, c, 2).
This should work for you, but as #ThreeFx suggested in the comments you need to mention if it is only for pairs or for triplets and so on as well.
Nevertheless, the answer assumes the latter case:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StackQuestionAnswersCS
{
class Program
{
static void Main(string[] args)
{
if (checkContains("HelloWorld", 'o')) Console.WriteLine("Contains Character");
else Console.WriteLine("Does not contain character");
Console.ReadLine();
}
static bool checkContains(string input, char character)
{
for (int i = 0; i < input.Length - 1; i++)
{
if (input[i] == character && input[i+1] == character) return true;
}
return false;
}
}
}
private static bool Manipulation(string p, char c)
{
return p.Contains(c.ToString() + c.ToString()) && !p.Replace(c.ToString() + c.ToString(), "").Contains(c);
}

Compare numeric values as string

I have a method which gets two string. These strings can contain numbers, ASCII chars or both at the same time.
The algorithm works like this:
Split both strings into char Arrays A and B.
Try to parse element Ai and Bi to an int
Compare element Ai with element Bi, in case of integers use direct comparison, in case of chars use ordinal string comparison.
Do work based on the result
Now, I'm wondering: Do I really need to parse the elements to int? I simply could compare each element in an ordinal string comparison and would get the same result, right?
What are the performance implications here? Is parsing and normal comparison faster than ordinal string comparison? Is it slower?
Is my assumption (using ordinal string comparison instead of parsing and comparing) correct?
Here is the method in question:
internal static int CompareComponentString(this string componentString, string other)
{
bool componentEmpty = string.IsNullOrWhiteSpace(componentString);
bool otherEmtpy = string.IsNullOrWhiteSpace(other);
if (componentEmpty && otherEmtpy)
{
return 0;
}
if (componentEmpty)
{
return -1;
}
if (otherEmtpy)
{
return 1;
}
string[] componentParts = componentString.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
string[] otherParts = other.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < Math.Min(componentParts.Length, otherParts.Length); i++)
{
string componentChar = componentParts[i];
string otherChar = otherParts[i];
int componentNumVal, otherNumVal;
bool componentIsNum = int.TryParse(componentChar, out componentNumVal);
bool otherIsNum = int.TryParse(otherChar, out otherNumVal);
if (componentIsNum && otherIsNum)
{
if (componentNumVal.CompareTo(otherNumVal) == 0)
{
continue;
}
return componentNumVal.CompareTo(otherNumVal);
}
else
{
if (componentIsNum)
{
return -1;
}
if (otherIsNum)
{
return 1;
}
int comp = string.Compare(componentChar, otherChar, StringComparison.OrdinalIgnoreCase);
if (comp != 0)
{
return comp;
}
}
}
return componentParts.Length.CompareTo(otherParts.Length);
}
This are strings that might be used. I might add only the part after the minus sign is used.
1.0.0-alpha
1.0.0-alpha.1
1.0.0-alpha.beta
1.0.0-beta.2
With this method you can create a compare string for each of your string. These strings are comparable by simple alphanumeric comparison.
Assumptions:
There is a minus in the string separating the common part and the indiv part
before the minus is always a substring of three integer values divided by a dot
These integer values are not higher than 999 (look at variable "MaxWidth1")
behind the minus is another substring consisting of several parts, also divided by a dot
The second substring's parts may be numeric or alphanumeric with a max. width of 7 (look at "MaxWidth2")
The second substring consists of max. 5 parts (MaxIndivParts)
Put this method wherever you want:
public string VersionNumberCompareString(string versionNumber, int MaxWidth1=3, int MaxWidth2=7,int MaxIndivParts=5){
string result = null;
int posMinus = versionNumber.IndexOf('-');
string part1 = versionNumber.Substring(0, posMinus);
string part2 = versionNumber.Substring(posMinus+1);
var integerValues=part1.Split('.');
result = integerValues[0].PadLeft(MaxWidth1, '0');
result += integerValues[1].PadLeft(MaxWidth1, '0');
result += integerValues[2].PadLeft(MaxWidth1, '0');
var alphaValues = part2.Split('.');
for (int i = 0; i < MaxIndivParts;i++ ) {
if (i <= alphaValues.GetUpperBound(0)) {
var s = alphaValues[i];
int casted;
if (int.TryParse(s, out casted)) //if int: treat as number
result += casted.ToString().PadLeft(MaxWidth2, '0');
else //treat as string
result += s.PadRight(MaxWidth2, ' ');
}
else
result += new string(' ', MaxWidth2);
}
return result; }
You call it like this:
var s1 = VersionNumberCompareString("1.3.0-alpha.1.12");
//"001003000alpha 00000010000012 "
var s2 = VersionNumberCompareString("0.11.4-beta");
//"000011004beta "
var s3 = VersionNumberCompareString("2.10.11-beta.2");
//"002010011beta 0000002 "
Be aware of the final " sign. All strings are of the same length!
Hope this helps...
that's .net comparison logic for ascii strings -
private unsafe static int CompareOrdinalIgnoreCaseHelper(String strA, String strB)
{
Contract.Requires(strA != null);
Contract.Requires(strB != null);
Contract.EndContractBlock();
int length = Math.Min(strA.Length, strB.Length);
fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar)
{
char* a = ap;
char* b = bp;
while (length != 0)
{
int charA = *a;
int charB = *b;
Contract.Assert((charA | charB) <= 0x7F, "strings have to be ASCII");
// uppercase both chars - notice that we need just one compare per char
if ((uint)(charA - 'a') <= (uint)('z' - 'a')) charA -= 0x20;
if ((uint)(charB - 'a') <= (uint)('z' - 'a')) charB -= 0x20;
//Return the (case-insensitive) difference between them.
if (charA != charB)
return charA - charB;
// Next char
a++; b++;
length--;
}
return strA.Length - strB.Length;
}
}
having said that, Unless you have a strict performance constaint, i would say if you get the same result from an already implemented & tested function, its better to reuse it and not to reinvent the wheel.
It saves so much time in implementation, unit testing, debugging & bug fixing time. & helps keep the software simple.

Categories

Resources