Why does my program duplicate output when it should not? - c#

My application basically takes a string of characters and counts how many times each of the alphabetic characters appears. It also ignores numbers being type. But it duplicates the same alphabets second time I input it.
Code:
string input = Console.ReadLine().ToUpper();
while (input[0] != 'q') {
int[] counting = new int[26];
Array.Clear(counting, 0, counting.Length);
//string to array conversion
if (input.Length > 0 && input.ToUpper()[0] == 'Q')
return;
string all = ".";
for (int i = 0; i < input.Length; i++) {
bool checking = false;
string number = "";
for (int j = 0; j < input.Length; j++) {
if (input.ToUpper()[i] == input.ToUpper()[j]) {
number += input.ToUpper()[i];
}
}
for (int j = 0; j < all.Length; j++) {
if (input[i] == all[j]) {
checking = true;
}
}
all += input[i];
if (!checking) {
input = Regex.Replace(input, # "[\d-]", string.Empty);
Console.Write(number[0].ToString() + number.Length.ToString() + " ");
}
}
Console.WriteLine();
input = Console.ReadLine();
It is supposed to only output "A6" which it did successfully the first time but stops on the second time.
Output:
aAaAaA
A6
aAaAaA
A6 A2

Related

Count Matching Subsequences

This is what I need to do:
Create a function that receives a text string, and a search string, and returns how many times the search string appears in the string, as a subsequence of its letters in order.
For example, if you receive the word "Hhoola" and the substring "hola", the answer would be 4, because you could take the first H with the first O (and with the L and with the A), the first H with the second O, the second H with the first O, or the second H with the second O. If you receive "hobla", the answer would be 1. If you receive "ohla", the answer would be 0, because after the H there is no O to complete the sequence in order.
This is what i got so far:
int count = 0;
void Function(string text, string subText)
{
for (int i = 0; i < text.Length; i++)
{
if (text[i] == subText[0])
{
for (int j = 0; j < subText.Length; j++)
{
if (text[i + j] != subText[j])
{
break;
}
if (j == subText.Length - 1)
{
count++;
}
}
}
}
}
string text = Console.ReadLine().ToLower();
string subText = Console.ReadLine().ToLower();
ReceibeText(text, subText);
The code should look like this. Code doesn't work but is close.
public class SubSequences
{
string input = "";
string word = "";
int count = 0;
public void FindMatches(string input, string word)
{
this.input = input;
this.word = word;
FindMatchesRecursive(0, 0);
}
public void FindMatchesRecursive(int inputIndex, int wordIndex)
{
for (int i = inputIndex; i < input.Length - word.Length; i++ )
{
for (int j = wordIndex; j < input.Length - word.Length; j++)
{
if (word.Substring(i) == input.Substring(j))
{
if (j == word.Length)
{
FindMatchesRecursive(i + 1, j + 1);
}
else
{
Console.WriteLine("Word Matches");
}
}
}
}
}

How I can check if substring contain another substring c#

//the word skill it's a substring for two string i want to compare based it
string first = "skill.Name";
string second = "jobskillRelation";
first.Contains(second);
You can use Longest Common Substring code provided here, the C# version is like this:
public static string lcs(string a, string b)
{
var lengths = new int[a.Length, b.Length];
int greatestLength = 0;
string output = "";
for (int i = 0; i < a.Length; i++)
{
for (int j = 0; j < b.Length; j++)
{
if (a[i] == b[j])
{
lengths[i, j] = i == 0 || j == 0 ? 1 : lengths[i - 1, j - 1] + 1;
if (lengths[i, j] > greatestLength)
{
greatestLength = lengths[i, j];
output = a.Substring(i - greatestLength + 1, greatestLength);
}
}
else
{
lengths[i, j] = 0;
}
}
}
return output;
}
so the usage will be:
var LCS = lcs(first,second)
If you want to compare two string to see if both contain a certain keyword, this may help.
Boolean compare(string first, string second, string keyword)
{
if (first.Contains(keyword) && second.Contains(keyword))
return true;
return false;
}

C# Need inputs in different lines

I am trying to create a program that is will take letters as input only and not duplicated. I am getting error when i put one letter in an input.
This is what i need to do, I need to get the user input in each line (like a enter, b enter, etc), if there is a duplication value i need a error message and continues with the input, and if there is incorrect value i get another error stating such. I cannot use LINQ, Hashset, nor list, it has to be arrays.
static void Main(string[] args)
{
char[] Array = new char[5];
Console.WriteLine("Please Enter 5 Letters B/W a through j only: ");
string letters = "abcdefghij";
char[] read = Console.ReadLine().ToLower().ToCharArray();
//loop through array
for (int i = 0; i < 5; i++)
{
if (letters.Contains(read[i]) && !Array.Contains(read[i]))
{
Array[i] = read[i];
}
else
{
Console.WriteLine("You have entered an incorrect value");
}
}
Console.WriteLine("You have Entered the following Inputs: ");
for (int i = 0; i < Array.Length; i++)
{
Console.WriteLine(Array[i]);
}
Console.ReadKey();
}
I think this more or less does what you want:
var max = 5;
var array = new char[max];
var letters = "abcdefghij";
var count = 0;
while (count < 5)
{
Console.WriteLine("Please Enter {0} Letters B/W a through j only: ", max);
var key = Console.ReadKey();
var read = key.KeyChar
if (!letters.Contains(read))
{
Console.WriteLine("You have entered an incorrect value");
continue;
}
var found = false;
for (int i = 0; i < count; i++)
{
if (array[i] == read)
{
found = true;
}
}
if (found)
{
Console.WriteLine("You have entered an duplicate value");
continue;
}
array[count++] = read;
}
Console.WriteLine("You have Entered the following Inputs: ");
for (int i = 0; i < array.Length; i++)
{
Console.WriteLine(array[i]);
}
Console.ReadKey();
If you want the user to enter the values individually then you would need to request each character in a loop.
Something like:
static void Main(string[] args)
{
const string validValues = "abcdefghij";
var enteredCharacters = new char[5];
for (int i = 0; i < enteredCharacters.Length; i++)
{
Console.WriteLine("Please enter a unique character between a and j");
var input = Console.ReadLine();
if (input.Length == 0)
{
Console.WriteLine("You did not enter a value.");
return;
}
if (input.Length > 1)
{
Console.WriteLine("You have entered more than 1 character");
return;
}
var character = input[0];
if (!validValues.Contains(character))
{
Console.WriteLine("You have entered an invalid character");
return;
}
if (enteredValues.Contains(character))
{
Console.WriteLine("You have already entered this character");
return;
}
enteredCharacters[i] = character;
}
// process numbers.
}
this is you problem
for (int i = 0; i < 5; i++)
this is your fix:
static void Main(string[] args)
{
char[] Array = new char[5];
Console.WriteLine("Please Enter 5 Letters B/W a through j only: ");
string letters = "abcdefghij";
char[] read = Console.ReadLine().ToLower().ToCharArray();
//loop through array
for (int i = 0; i < read.Length; i++)
{
if (letters.Contains(read[i]) && !Array.Contains(read[i]))
{
Array[i] = read[i];
}
else
{
Console.WriteLine("You have entered an incorrect value");
}
}
Console.WriteLine("You have Entered the following Inputs: ");
for (int i = 0; i < Array.Length; i++)
{
Console.WriteLine(Array[i]);
}
Console.ReadKey();
}

C# How to get the length of chars in a string

I have a []string retry and I have some strings inside of it let's say:
a 2 , a 3 , h 9, asd 123 and so on. They all have intervals between the letter and the integer. Now I need to get how long is the letter part (in this case "qwe 2" the letter length is 3 and the integer part is 2). I'm later using .substring from the specified index at which the letter part finishes and the integer one starts.
string[] s = new string[5];
List<string> retry = new List<string>();
int max = 1;
for (int i = 0; i < s.Length; i++)
{
s[i] = Console.ReadLine();
}
Console.WriteLine(" ");
Array.Sort(s);
for (int j = 0; j < s.Length; j++)
{
if (j > 0)
{
if (s[j] == s[j - 1])
{
max++;
if (retry.Any(x => x.Contains(s[j])))
{
retry.Add(s[j] + " " + max);
}
else
{
if (j <= s.Length - 1)
{
if (s[j-1] != s[j])
{
retry.Add(s[j] + " " + max);
}
else
{
retry.Add(s[j] + " " + max);
}
}
}
}
else
{
max = 1;
}
}
}
for (int j = 0; j < retry.ToArray().Length; j++)
{
for (int k = j + 1; k < retry.ToArray().Length; k++)
{
var a1=retry[j].Substring(0,1);
var a2 = retry[k].Substring(0,1);
if(a1==a2)
{
var b1 = retry[j].Substring(2);
var b2 = retry[k].Substring(2);
if(int.Parse(b1)>int.Parse(b2))
{
retry.Remove(a2 + " "+ b2);
}
else
{
retry.Remove(a1 + " " + b1);
}
}
}
Console.WriteLine(retry[j]);
}
Console.ReadKey();
This only works for 1 letter.
The code below should get the result as expected:
string [] entries = {"xyz 1","q 2","poiuy 4"};
for(int i=0;i<entries.Length;i++)
{
var parts = entries[i].Split(' ');
var txtCount = parts[0].Length;
Console.WriteLine(String.Format("{0} {1}", txtCount, parts[1]));
}
How about...
string[] test = new [] { "qwe 2", "a 2", "b 3", "asd 123" };
foreach (var s in test)
{
var lastLetterIndex = Array.FindLastIndex(s.ToCharArray(), Char.IsLetter);
var lastNumberIndex = Array.FindLastIndex(s.ToCharArray(), Char.IsNumber);
Console.WriteLine(s);
Console.WriteLine("Letter Length : " + (lastLetterIndex + 1));
Console.WriteLine("Number Length : " + (lastNumberIndex - lastLetterIndex));
}
Console.ReadKey();
This iterates through all of the strings and counts the length of the chars, and stores the value of the number, as well as its index. Note that this information is lost upon each iteration, but I'll leave it to you to worry about storing that if you need that information for longer than the duration of an iteration.
int letterLength = 0, number = 0, index = 0;
string[] testString = { "a 2", "a 3", "h 9", "asd 123", "sw", "swa23", "swag 2464" };
foreach (string str in testString)
{
letterLength = 0;
index = -1;
int i = 0;
for (; i < str.Length; i++)
{
char c = str[i];
if (Char.IsLetter(c)) letterLength++;
else if (Char.IsNumber(c)) break;
}
StringBuilder strBuilder = new StringBuilder();
for (; i < str.Length; i++)
{
char c = str[i];
if (index == -1) index = str.IndexOf(c);
strBuilder.Append(c);
number = Int32.Parse(strBuilder.ToString());
}
Console.WriteLine($"String: {str}\nLetter Length: {letterLength} Number: {number} Index: {index}\n");
}

Longest Common Subsequence

Hi this is my code for longest common subsequence for 2 strings in c# . I need help in backtracking . I need to find out the subsequence : GTCGT
String str1 = "GTCGTTCG";
String str2 = "ACCGGTCGAGTG";
int[,] l = new int[str1.Length, str2.Length]; // String 1 length and string 2 length storing it in a 2-dimensional array
int lcs = -1;
string substr = string.Empty;
int end = -1;
for (int i = 0; i <str1.Length ; i++) // Looping based on string1 length
{
for (int j = 0; j < str2.Length; j++) // Looping based on string2 Length
{
if (str1[i] == str2[j]) // if match found
{
if (i == 0 || j == 0) // i is first element or j is first elemnt then array [i,j] = 1
{
l[i, j] = 1;
}
else
{
l[i, j] = l[i - 1, j - 1] + 1; // fetch the upper value and increment by 1
}
if (l[i, j] > lcs)
{
lcs = l[i, j]; // store lcs value - how many time lcs is found
end = i; // index on longest continuous string
}
}
else // if match not found store zero initialze the array value by zero
{
l[i, j] = 0;
}
}
Your function needs to return a collection of strings. There might be several longest common sub-sequence with same length.
public List<string> LCS(string firstString, string secondString)
{
// to create the lcs table easier which has first row and column empty.
string firstStringTemp = " " + firstString;
string secondStringTemp = " " + secondString;
// create the table
List<string>[,] temp = new List<string>[firstStringTemp.Length, secondStringTemp.Length];
// loop over all items in the table.
for (int i = 0; i < firstStringTemp.Length; i++)
{
for (int j = 0; j < secondStringTemp.Length; j++)
{
temp[i, j] = new List<string>();
if (i == 0 || j == 0) continue;
if (firstStringTemp[i] == secondStringTemp[j])
{
var a = firstStringTemp[i].ToString();
if (temp[i - 1, j - 1].Count == 0)
{
temp[i, j].Add(a);
}
else
{
foreach (string s in temp[i - 1, j - 1])
{
temp[i, j].Add(s + a);
}
}
}
else
{
List<string> b = temp[i - 1, j].Concat(temp[i, j - 1]).Distinct().ToList();
if (b.Count == 0) continue;
int max = b.Max(p => p.Length);
b = b.Where(p => p.Length == max).ToList();
temp[i, j] = b;
}
}
}
return temp[firstStringTemp.Length - 1, secondStringTemp.Length - 1];
}
You need to have a collection set in each entry of table. So you can still keep different strings with the same length in each cell of table.
As far as I've understood your question, I think you want to know the subsequence value i.e. that string. So, to get the subsequence, I've learnt a little bit differently. First, I calculate the table the one we do in standard Longest Common Subsequence (LCS) problem. Then I traverse the table to get the subsequence value. Sorry, I'm not familiar with C#, so, I will give you CPP code. Please have a look and let me know if you face any problem.
#include<iostream>
#include<vector>
#include<string>
using namespace std;
string printLongestCommonSubsequence(vector<vector<int> >& dp, int m, int n, string text1, string text2){
int i = m, j = n;
string lcs = "";
while(i > 0 && j > 0){
if(text1[i-1] == text2[j-1]){
lcs.push_back(text1[i-1]);
i--; j--;
}
else{
if(dp[i][j-1] > dp[i-1][j]) j--;
else i--;
}
}
reverse(lcs.begin(), lcs.end());
return lcs;
}
string longestCommonSubsequence(string text1, string text2){
int m = text1.size();
int n = text2.size();
vector<vector<int> > dp(m+1, vector<int>(n+1));
//initialization
for(int i=0; i<m+1; i++){
for(int j=0; j<n+1; j++){
if(i == 0 || j == 0) dp[i][j] = 0;
}
}
//solving the subproblems to solve the bigger problems
for(int i=1; i<m+1; i++){
for(int j=1; j<n+1; j++){
if(text1[i-1] == text2[j-1])
dp[i][j] = 1 + dp[i-1][j-1];
else
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
return printLongestCommonSubsequence(dp, m, n, text1, text2);
}
int main(){
string text1, text2;
cout<<"Enter the first string: ";
cin>>text1;
cout<<"\nEnter the second string: ";
cin>>text2;
string lcs = longestCommonSubsequence(text1, text2);
cout<<"Longest Common Subsequence is: "<<lcs<<endl;
return(0);
}
Please have a look at the diagram.
With respect to printing the LCS,
The basic idea is:
When the characters are equal of both the strings then move towards diagonal.
When the characters are not equal of both the strings then move towards the maximum of both the directions.
I hope this helps 🙂
Happy Learning
Thanks

Categories

Resources