This question already has answers here:
How would you count occurrences of a string (actually a char) within a string?
(34 answers)
Closed 6 years ago.
I need some help figure this one out. I need to search a string within a string and return the number of occurrences. I have tried the code below and it works and i also tried to use a regex and it worked but my teacher said to pretend that i can't use the indexOf or the regex. I know there have been some similar questions but that didn't help me much since they all use IndexOf or regex. So any ideas please?
What I have tried:
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
string s1 = "hellohjhghello";
string s2 = "he";
var r = Occurrences(s1, s2);
Console.WriteLine("{0} is repeated {1} times", s2, r);
}
static int Occurrences(string s1, string s2)
{
int count = 0;
int pos = 0;
while((pos = s1.IndexOf(s2,pos)) > -1)
{
count++;
pos += s2.Length;
}
return count;
}
}
}
EDIT:
I don't know what my teacher expects me to so but in another exercise I did a search for a char in string. He said to do something similar but for a string. My previous exercise goes like this:
class ex3
{
static void Main(string[] args)
{
string str = "aaabekldfj";
char letter = 'a';
var r = Occurrences(str, letter);
Console.WriteLine("The letter '{0}' from string '{1}' has {2} occurrences", letter, str,r);
}
static int Occurences(string str, char letter)
{
int repeat = 0;
for(int i=0; i< str.Length; i++)
{
if (str[i] == letter)
repeat++;
}
return repeat;
}
}
Why not keep it simple?
string compareText = "hello! This is a string to check hello's in this string!";
string compareWord = "hello";
int occurrences = (compareText.Length - compareText.Replace(compareWord, string.Empty).Length) / compareWord.Length;
Without indexof and regex and keeping it simple (but not fast), you can do following
static int OccurrencesAdvanced(string s1, string s2)
{
var result = 0;
for (var i = 0; i <= (s1.Length - s2.Length); i++)
{
var tested = s1.Substring(i, s2.Length);
if (string.Compare(tested, s2) == 0)
{
i += Math.Max(1, s2.Length - 1);
result++;
}
}
return result;
}
Here is my idea what first came in my mind. I don't know currently where are you in your studies so this solution might not good for you.
class Program
{
static void Main(string[] args)
{
var s1 = "hellohjhghello";
var s2 = "lo";
var occurence = 0;
Occurrences(s1, s2, ref occurence);
Console.WriteLine("{0} is repeated {1} times", s2, occurence);
Console.ReadLine();
}
static void Occurrences(string s1, string s2, ref int occurence)
{
var index = s1.IndexOf(s2);
if (index > -1)
{
occurence++;
s1 = s1.Substring(index + s2.Length);
Occurrences(s1, s2, ref occurence);
}
}
}
I have a string as input and have to break the string in two substrings. If the left substring equals the right substring then do some logic.
How can I do this?
Sample:
public bool getStatus(string myString)
{
}
Example: myString = "ankYkna", so if we break it into two substring it would be:
left-part = "ank",
right-part = "ank" (after reversal).
Just for fun:
return myString.SequenceEqual(myString.Reverse());
public static bool getStatus(string myString)
{
string first = myString.Substring(0, myString.Length / 2);
char[] arr = myString.ToCharArray();
Array.Reverse(arr);
string temp = new string(arr);
string second = temp.Substring(0, temp.Length / 2);
return first.Equals(second);
}
int length = myString.Length;
for (int i = 0; i < length / 2; i++)
{
if (myString[i] != myString[length - i - 1])
return false;
}
return true;
Using LINQ and off course far from the best solution
var original = "ankYkna";
var reversed = new string(original.Reverse().ToArray());
var palindrom = original == reversed;
A single line of code using Linq
public static bool IsPalindrome(string str)
{
return str.SequenceEqual(str.Reverse());
}
public static bool IsPalindrome(string value)
{
int i = 0;
int j = value.Length - 1;
while (true)
{
if (i > j)
{
return true;
}
char a = value[i];
char b = value[j];
if (char.ToLower(a) != char.ToLower(b))
{
return false;
}
i++;
j--;
}
}
//This c# method will check for even and odd lengh palindrome string
public static bool IsPalenDrome(string palendromeString)
{
bool isPalenDrome = false;
try
{
int halfLength = palendromeString.Length / 2;
string leftHalfString = palendromeString.Substring(0,halfLength);
char[] reversedArray = palendromeString.ToCharArray();
Array.Reverse(reversedArray);
string reversedString = new string(reversedArray);
string rightHalfStringReversed = reversedString.Substring(0, halfLength);
isPalenDrome = leftHalfString == rightHalfStringReversed ? true : false;
}
catch (Exception ex)
{
throw ex;
}
return isPalenDrome;
}
In C# :
public bool EhPalindromo(string text)
{
var reverseText = string.Join("", text.ToLower().Reverse());
return reverseText == text;
}
This is a short and efficient way of checking palindrome.
bool checkPalindrome(string inputString) {
int length = inputString.Length;
for(int i = 0; i < length/2; i++){
if(inputString[i] != inputString[length-1-i]){
return false;
}
}
return true;
}
This way is both concise in appearance & processes very quickly.
Func<string, bool> IsPalindrome = s => s.Reverse().Equals(s);
public static bool IsPalindrome(string word)
{
//first reverse the string
string reversedString = new string(word.Reverse().ToArray());
return string.Compare(word, reversedString) == 0 ? true : false;
}
Out of all the solutions, below can also be tried:
public static bool IsPalindrome(string s)
{
return s == new string(s.Reverse().ToArray());
}
String extension method, easy to use:
public static bool IsPalindrome(this string str)
{
str = new Regex("[^a-zA-Z]").Replace(str, "").ToLower();
return !str.Where((t, i) => t != str[str.Length - i - 1]).Any();
}
private void CheckIfPalindrome(string str)
{
//place string in array of chars
char[] array = str.ToCharArray();
int length = array.Length -1 ;
Boolean palindrome =true;
for (int i = 0; i <= length; i++)//go through the array
{
if (array[i] != array[length])//compare if the char in the same positions are the same eg "tattarrattat" will compare array[0]=t with array[11] =t if are not the same stop the for loop
{
MessageBox.Show("not");
palindrome = false;
break;
}
else //if they are the same make length smaller by one and do the same
{
length--;
}
}
if (palindrome) MessageBox.Show("Palindrome");
}
use this way from dotnetperls
using System;
class Program
{
/// <summary>
/// Determines whether the string is a palindrome.
/// </summary>
public static bool IsPalindrome(string value)
{
int min = 0;
int max = value.Length - 1;
while (true)
{
if (min > max)
{
return true;
}
char a = value[min];
char b = value[max];
// Scan forward for a while invalid.
while (!char.IsLetterOrDigit(a))
{
min++;
if (min > max)
{
return true;
}
a = value[min];
}
// Scan backward for b while invalid.
while (!char.IsLetterOrDigit(b))
{
max--;
if (min > max)
{
return true;
}
b = value[max];
}
if (char.ToLower(a) != char.ToLower(b))
{
return false;
}
min++;
max--;
}
}
static void Main()
{
string[] array =
{
"A man, a plan, a canal: Panama.",
"A Toyota. Race fast, safe car. A Toyota.",
"Cigar? Toss it in a can. It is so tragic.",
"Dammit, I'm mad!",
"Delia saw I was ailed.",
"Desserts, I stressed!",
"Draw, O coward!",
"Lepers repel.",
"Live not on evil.",
"Lonely Tylenol.",
"Murder for a jar of red rum.",
"Never odd or even.",
"No lemon, no melon.",
"Senile felines.",
"So many dynamos!",
"Step on no pets.",
"Was it a car or a cat I saw?",
"Dot Net Perls is not a palindrome.",
"Why are you reading this?",
"This article is not useful.",
"...",
"...Test"
};
foreach (string value in array)
{
Console.WriteLine("{0} = {1}", value, IsPalindrome(value));
}
}
}
If you just need to detect a palindrome, you can do it with a regex, as explained here. Probably not the most efficient approach, though...
That is non-trivial, there is no built in method to do that for you, you'll have to write your own. You will need to consider what rules you would like to check, like you implicitly stated you accepted reversing of one string. Also, you missed out the middle character, is this only if odd length?
So you will have something like:
if(myString.length % 2 = 0)
{
//even
string a = myString.substring(0, myString.length / 2);
string b = myString.substring(myString.length / 2 + 1, myString.lenght/2);
if(a == b)
return true;
//Rule 1: reverse
if(a == b.reverse()) //can't remember if this is a method, if not you'll have to write that too
return true;
etc, also doing whatever you want for odd strings
This C# method will check for even and odd length palindrome string (Recursive Approach):
public static bool IsPalindromeResursive(int rightIndex, int leftIndex, char[] inputString)
{
if (rightIndex == leftIndex || rightIndex < leftIndex)
return true;
if (inputString[rightIndex] == inputString[leftIndex])
return IsPalindromeResursive(--rightIndex, ++leftIndex, inputString);
else
return false;
}
public Boolean IsPalindrome(string value)
{
var one = value.ToList<char>();
var two = one.Reverse<char>().ToList();
return one.Equals(two);
}
class Program
{
static void Main(string[] args)
{
string s, revs = "";
Console.WriteLine(" Enter string");
s = Console.ReadLine();
for (int i = s.Length - 1; i >= 0; i--) //String Reverse
{
Console.WriteLine(i);
revs += s[i].ToString();
}
if (revs == s) // Checking whether string is palindrome or not
{
Console.WriteLine("String is Palindrome");
}
else
{
Console.WriteLine("String is not Palindrome");
}
Console.ReadKey();
}
}
public bool IsPalindroom(string input)
{
input = input.ToLower();
var loops = input.Length / 2;
var higherBoundIdx = input.Length - 1;
for (var lowerBoundIdx = 0; lowerBoundIdx < loops; lowerBoundIdx++, higherBoundIdx--)
{
if (input[lowerBoundIdx] != input[higherBoundIdx])
return false;
}
return true;
}
Here is an absolutely simple way to do this,
Receive the word as input into a method.
Assign a temp variable to the original value.
Loop through the initial word, and add the last character to the reversal that you are constructing until the inital word has no more characters.
Now use the spare you created to hold the original value to compare to the constructed copy.
This is a nice way as u don't have to cast ints and doubles. U can just pass them to the method in their string representation by using the ToString() method.
public static bool IsPalindrome(string word)
{
string spare = word;
string reversal = null;
while (word.Length > 0)
{
reversal = string.Concat(reversal, word.LastOrDefault());
word = word.Remove(word.Length - 1);
}
return spare.Equals(reversal);
}
So from your main method,
For even and odd length strings u just pass the whole string into the method.
Since a palindrome also includes numbers, words, sentences, and any combinations of these, and should ignore punctuation and case, (See Wikipedia Article)
I propose this solution:
public class Palindrome
{
static IList<int> Allowed = new List<int> {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'1', '2', '3', '4', '5', '6', '7', '8', '9',
'0'
};
private static int[] GetJustAllowed(string text)
{
List<int> characters = new List<int>();
foreach (var c in text)
characters.Add(c | 0x20);
return characters.Where(c => Allowed.Contains(c)).ToArray();
}
public static bool IsPalindrome(string text)
{
if(text == null || text.Length == 1)
return true;
int[] chars = GetJustAllowed(text);
var length = chars.Length;
while (length > 0)
if (chars[chars.Length - length] != chars[--length])
return false;
return true;
}
public static bool IsPalindrome(int number)
{
return IsPalindrome(number.ToString());
}
public static bool IsPalindrome(double number)
{
return IsPalindrome(number.ToString());
}
public static bool IsPalindrome(decimal number)
{
return IsPalindrome(number.ToString());
}
}
static void Main(string[] args)
{
string str, rev="";
Console.Write("Enter string");
str = Console.ReadLine();
for (int i = str.Length - 1; i >= 0; i--)
{
rev = rev + str[i];
}
if (rev == str)
Console.Write("Entered string is pallindrome");
else
Console.Write("Entered string is not pallindrome");
Console.ReadKey();
}
string test = "Malayalam";
char[] palindrome = test.ToCharArray();
char[] reversestring = new char[palindrome.Count()];
for (int i = palindrome.Count() - 1; i >= 0; i--)
{
reversestring[palindrome.Count() - 1 - i] = palindrome[i];
}
string materializedString = new string(reversestring);
if (materializedString.ToLower() == test.ToLower())
{
Console.Write("Palindrome!");
}
else
{
Console.Write("Not a Palindrome!");
}
Console.Read();
public static bool palindrome(string t)
{
int i = t.Length;
for (int j = 0; j < i / 2; j++)
{
if (t[j] == t[i - j-1])
{
continue;
}
else
{
return false;
break;
}
}
return true;
}
public bool Solution(string content)
{
int length = content.Length;
int half = length/2;
int isOddLength = length%2;
// Counter for checking the string from the middle
int j = (isOddLength==0) ? half:half+1;
for(int i=half-1;i>=0;i--)
{
if(content[i] != content[j])
{
return false;
}
j++;
}
return true;
}
public bool MojTestPalindrome (string word)
{
bool yes = false;
char[]test1 = word.ToArray();
char[] test2 = test1.Reverse().ToArray();
for (int i=0; i< test2.Length; i++)
{
if (test1[i] != test2[test2.Length - 1 - i])
{
yes = false;
break;
}
else {
yes = true;
}
}
if (yes == true)
{
return true;
}
else
return false;
}
public static bool IsPalindrome(string str)
{
int i = 0;
int a = 0;
char[] chr = str.ToCharArray();
foreach (char cr in chr)
{
Array.Reverse(chr);
if (chr[i] == cr)
{
if (a == str.Length)
{
return true;
}
a++;
i++;
}
else
{
return false;
}
}
return true;
}
The various provided answers are wrong for numerous reasons, primarily from misunderstanding what a palindrome is. The majority only properly identify a subset of palindromes.
From Merriam-Webster
A word, verse, or sentence (such as "Able was I ere I saw Elba")
And from Wordnik
A word, phrase, verse, or sentence that reads the same backward or forward. For example: A man, a plan, a canal, Panama!
Consider non-trivial palindromes such as "Malayalam" (it's a proper language, so naming rules apply, and it should be capitalized), or palindromic sentences such as "Was it a car or a cat I saw?" or "No 'X' in Nixon".
These are recognized palindromes in any literature.
I'm lifting the thorough solution from a library providing this kind of stuff that I'm the primary author of, so the solution works for both String and ReadOnlySpan<Char> because that's a requirement I've imposed on the library. The solution for purely String will be easy to determine from this, however.
public static Boolean IsPalindrome(this String #string) =>
!(#string is null) && #string.AsSpan().IsPalindrome();
public static Boolean IsPalindrome(this ReadOnlySpan<Char> span) {
// First we need to build the string without any punctuation or whitespace or any other
// unrelated-to-reading characters.
StringBuilder builder = new StringBuilder(span.Length);
foreach (Char s in span) {
if (!(s.IsControl()
|| s.IsPunctuation()
|| s.IsSeparator()
|| s.IsWhiteSpace()) {
_ = builder.Append(s);
}
}
String prepped = builder.ToString();
String reversed = prepped.Reverse().Join();
// Now actually check it's a palindrome
return String.Equals(prepped, reversed, StringComparison.CurrentCultureIgnoreCase);
}
You're going to want variants of this that accept a CultureInfo parameter as well, when you're testing a specific language rather than your own language, by instead calling .ToUpper(cultureInfo) on prepped.
And here's proof from the projects unit tests that it works.
I have to implements a function that takes a string as an input and finds the non-duplicate character from this string.
So an an example is if I pass string str = "DHCD" it will return "DHC"
or str2 = "KLKLHHMO" it will return "KLHMO"
A Linq approach:
public static string RemoveDuplicates(string input)
{
return new string(input.ToCharArray().Distinct().ToArray());
}
It will do the job
string removedupes(string s)
{
string newString = string.Empty;
List<char> found = new List<char>();
foreach(char c in s)
{
if(found.Contains(c))
continue;
newString+=c.ToString();
found.Add(c);
}
return newString;
}
I should note this is criminally inefficient.
I think I was delirious on first revision.
For arbitrary length strings of byte-sized characters (not for wide characters or other encodings), I would use a lookup table, one bit per character (32 bytes for a 256-bit table). Loop through your string, only output characters that don't have their bits turned on, then turn the bit on for that character.
string removedupes(string s)
{
string t;
byte[] found = new byte[256];
foreach(char c in s)
{
if(!found[c]) {
t.Append(c);
found[c]=1;
}
}
return t;
}
I am not good with C#, so I don't know the right way to use a bitfield instead of a byte array.
If you know that your strings are going to be very short, then other approaches would offer better memory usage and/or speed.
void removeDuplicate()
{
string value1 = RemoveDuplicateChars("Devarajan");
}
static string RemoveDuplicateChars(string key)
{
string result = "";
foreach (char value in key)
if (result.IndexOf(value) == -1)
result += value;
return result;
}
It sounds like homework to me, so I'm just going to describe at a high level.
Loop over the string, examining each character
Check if you've seen the character before
if you have, remove it from the string
if you haven't, note that you've now seen that character
this is in C#. validation left out for brevity. primitive solution for removing duplicate chars from a given string
public static char[] RemoveDup(string s)
{
char[] chars = new char[s.Length];
int unique = 0;
chars[unique] = s[0]; // Assume: First char is unique
for (int i = 1; i < s.Length; i++)
{
// add char in i index to unique array
// if char in i-1 != i index
// i.e s = "ab" -> a != b
if (s[i-1] != s[i]
chars[++unique] = s[i];
}
return chars;
}
My answer in java language.
Posting here so that you might get a idea even it is in Java language.Algorithm would remain same.
public String removeDup(String s)
{
if(s==null) return null;
int l = s.length();
//if length is less than 2 return string
if(l<2)return s;
char arr[] = s.toCharArray();
for(int i=0;i<l;i++)
{
int j =i+1; //index to check with ith index
int t = i+1; //index of first repetative char.
while(j<l)
{
if(arr[j]==arr[i])
{
j++;
}
else
{
arr[t]=arr[j];
t++;
j++;
}
}
l=t;
}
return new String(arr,0,l);
}
you may use HashSet:
static void Main()
{
string textWithDuplicates = "aaabbcccggg";
Console.WriteLine(textWithDuplicates.Count());
var letters = new HashSet<char>(textWithDuplicates);
Console.WriteLine(letters.Count());
foreach (char c in letters) Console.Write(c);
}
class Program
{
static void Main(string[] args)
{
bool[] doesExists = new bool[256];
String st = Console.ReadLine();
StringBuilder sb = new StringBuilder();
foreach (char ch in st)
{
if (!doesExists[ch])
{
sb.Append(ch);
doesExists[ch] = true;
}
}
Console.WriteLine(sb.ToString());
}
}
Revised version of the first answer i.e: You don't need ToCharArray() function for this to work.
public static string RemoveDuplicates(string input)
{
return new string(input.Distinct().ToArray());
}
char *remove_duplicates(char *str)
{
char *str1, *str2;
if(!str)
return str;
str1 = str2 = str;
while(*str2)
{
if(strchr(str, *str2)<str2)
{
str2++;
continue;
}
*str1++ = *str2++;
}
*str1 = '\0';
return str;
}
char* removeDups(const char* str)
{
char* new_str = (char*)malloc(256*sizeof(char));
int i,j,current_pos = 0,len_of_new_str;
new_str[0]='\0';
for(i=0;i<strlen(str);i++)
{
len_of_new_str = strlen(new_str);
for(j=0;j<len_of_new_str && new_str[j]!=str[i];j++)
;
if(j==len_of_new_str)
{
new_str[len_of_new_str] = str[i];
new_str[len_of_new_str+1] = '\0';
}
}
return new_str;
}
Hope this helps
String str="AABBCANCDE";
String newStr="";
for( int i=0; i<str.length(); i++)
{
if(!newStr.contains(str.charAt(i)+""))
newStr= newStr+str.charAt(i);
}
System.out.println(newStr);
// Remove both upper-lower duplicates
public static string RemoveDuplicates(string key)
{
string Result = string.Empty;
foreach (char a in key)
{
if (Result.Contains(a.ToString().ToUpper()) || Result.Contains(a.ToString().ToLower()))
continue;
Result += a.ToString();
}
return Result;
}
var input1 = Console.ReadLine().ToLower().ToCharArray();
var input2 = input1;
var WithoutDuplicate = input1.Union(input2);
Console.WriteLine("Enter String");
string str = Console.ReadLine();
string result = "";
result += str[0]; // first character of string
for (int i = 1; i < str.Length; i++)
{
if (str[i - 1] != str[i])
result += str[i];
}
Console.WriteLine(result);
I like Quintin Robinson answer, only there should be some improvements like removing List, because it is not necessarry in this case.
Also, in my opinion Uppercase char ("K") and lowercase char ("k") is the same thing, so they should be counted as one.
So here is how I would do it:
private static string RemoveDuplicates(string textEntered)
{
string newString = string.Empty;
foreach (var c in textEntered)
{
if (newString.Contains(char.ToLower(c)) || newString.Contains(char.ToUpper(c)))
{
continue;
}
newString += c.ToString();
}
return newString;
}
Not sure how optimal it is:
public static string RemoveDuplicates(string input)
{
var output = string.Join("", input.ToHashSet());
return output;
}
Below is the code to remove duplicate chars from a string
var input = "SaaSingeshe";
var filteredString = new StringBuilder();
foreach(char c in input)
{
if(filteredString.ToString().IndexOf(c)==-1)
{
filteredString.Append(c);
}
}
Console.WriteLine(filteredString);
Console.ReadKey();
namespace Demo { class Program {
static void Main(string[] args) {
string myStr = "kkllmmnnouo";
Console.WriteLine("Initial String: "+myStr);
// var unique = new HashSet<char>(myStr);
HashSet<char> unique = new HashSet<char>(myStr);
Console.Write("New String after removing duplicates: ");
foreach (char c in unique)
Console.Write(c);
} } }
this works for me
private string removeDuplicateChars(String value)
{
return new string(value.Distinct().ToArray());
}