Find biggest concatenation word in array - c#

I'm new to C#, can someone help me understand why my code doesnt work?
Seems like there something wrong with variable word which needs to be returned, but I don't understand what.
public virtual bool concatOnly()
{
int tmp = 0;
foreach (string word in words)
{
tmp += word.Length;
}
return (tmp <= word.Length);
}
I also don't really understand what I need to do in this:
public virtual void removeRepeat()
{
IEnumerator<string> iterator = words.GetEnumerator();
string checkWord = null;
while (iterator.MoveNext())
{
checkWord = iterator.Current;
foreach (string tmpWord in words)
{
if (tmpWord.Contains(checkWord) && checkWord.Length < tmpWord.Length)
{
iterator.Remove();
break;
}
}
}
}
Here's my full code

Update 3
In order to fix the second compile error (see Update 2), you need to remove from the list without doing so via Iterator, which has no remove method. One way would be the following, which saves up the indexes for removal after traversal by the iterator. Note that I remove the indexes in reverse order, so that the index numbers to be removed are not changed by prior removals.
public virtual void removeRepeat()
{
IEnumerator<string> iterator = words.GetEnumerator();
string checkWord = null;
List<int> removeIndexes = new List<int>();
int i = -1;
while (iterator.MoveNext())
{
checkWord = iterator.Current;
i++;
foreach (string tmpWord in words)
{
if (tmpWord.Contains(checkWord) && checkWord.Length < tmpWord.Length)
{
removeIndexes.Add(i);
break;
}
}
}
removeIndexes.Reverse();
foreach(var index in removeIndexes) {
words.RemoveAt(index);
}
}
Update 2
After fixing the first compile error (see my original answer below, which now works), your code is still giving this compile error main.cs(90,38): error CS1061: TypeSystem.Collections.Generic.IEnumerator' does not contain a definition for Remove' and no extension methodRemove' of typ
e `System.Collections.Generic.IEnumerator' could be found.
Update
I've changed my original answer to something that at least compiles. What I did is to change the original return (tmp <= word.Length); back to using word, which is the class member variable, not the local variable.
Original
Change the name of variable word in method concatOnly():
public virtual bool concatOnly()
{
int tmp = 0;
foreach (string w in words)
{
tmp += w.Length;
}
return (tmp <= word.Length);
}
This is because your class ConcatWord, of which concatOnly is a member method, already has a member variable named word: internal string word;.
FYI, the above shows that you also need to post the full code for the class ConcatWord. It's fine to give the link to the full code that you provided, that can be helpful, but everything required to reproduce the error also needs to be present in your question here at SO.

Related

Why are these functions displayed as not returning a value?

the two functions
the errors that they return
I'm using Visual Studio 2019
I tried re-writing these functions in different places in the code, it changed nothing.
You need to move the second return outside of the foreach - the way it's written - it will always return after the first element, and does not return anything if the collection is empty (which is the reason for the error).
If you paste the code as text instead of images, I can give the exact correct code.
Please see the corrected code below:
static Location locationMenu()
{
Console.WriteLine("Enter name of location \n");
foreach (Location l in availableLocations)
{
Console.WriteLine(l.getName());
}
string choice = Console.ReadLine();
foreach (Location l in availableLocations)
{
if (l.getName() == choice)
{
return l;
}
}
return null;
}
static int numberComplete()
{
int count = 0;
foreach (Location l in availableLocations)
{
if (l.getComplete())
{
count++;
}
}
return count;
}

How to display the index and index+1 of a foreach loop?

I am writing a program which loops through every object in a string[] array to find an object which contains a given string.
I then need to display that object and the following object, however, I can only seem to get the object that contains the given string and cannot get the object directly following as well.
static void Search_Level_2()
{
bool check = false;
WriteLine("Search Level 2:\nChecking if sequence {0} is in file...", inputArray[3]);
foreach (string line in sequences)
{
if (line.Contains(inputArray[3]))
{
WriteLine("Sequence Found!");
WriteLine(line.ToString());
check = true;
}
}
if (!check)
{
WriteLine("Error: Sequence {0} not found", inputArray[3]);
}
}
You cannot do this with a foreach because behind the scenes foreach gets an enumerator on the collection you're accessing and every time the loop comes round, it calls MoveNext() on the enumerator. There isn't any access to that enumerator for you if foreach set it up but you're not prohibited from getting an enumerator yourself and calling next yourself to get the next item.. Buuuut there's no way to move the enumerator backwards so you start having to build hacks in to remember what was this time's next so that in the next iteration you can recall it as the current.. messy
Use a classic for instead:
for(int x = 0; x < sequences.Length-1; x++)
{
var curr = sequences[x];
var next = sequences[x+1];
}
Note the loop runs to (less than Length-1) so the attempt to access x+1 doesn't cause a crash on the last item
You could try something along these lines:
static void Search_Level_2()
{
bool check = false;
WriteLine("Search Level 2:\nChecking if sequence {0} is in file...", inputArray[3]);
foreach (string line in sequences)
{
if (check)
{
WriteLine("Next line:");
WriteLine(line);
break;
}
if (line.Contains(inputArray[3]))
{
WriteLine("Sequence Found!");
WriteLine(line);
check = true;
}
}
if (!check)
{
WriteLine("Error: Sequence {0} not found", inputArray[3]);
}
}
I'm assuming that you want to only report the first occurrence and the line following the match.

search string inside string

I'm working on application that's need search method I have listbox full with items every item have singer name and song title , I need be able to search the song title or singer name on same method that's what's I tried so far :
public void search_song()
{
for (int i = listbox_titles.Items.Count - 1; i >= 0; i--)
{
int char_count = listbox_titles.Items[i].ToString().Length;
if (listbox_titles.Items[i].ToString().ToLower().Contains(txt_to_search.Text) || listbox_titles.Items[i].ToString().StartsWith(txt_to_search.Text, StringComparison.Ordinal) || listbox_titles.Items[i].ToString().ToLower().Substring(0, char_count).Contains(txt_to_search.Text)) ;
{
//listbox_titles.SetSelected(i, true);
MessageBox.Show(listbox_titles.Items[i].ToString());
}
}
its work but only search from the beginning of items not middle
any ideas ??
this example of what's I want if item is **avicii waiting for love ** if I search waiting for love is should give me the item .
You just need to find the list box item that contains what you search for, so you don't need for StartsWith method, but since you're saying that your search method only works on the starting string, I can find that you're not converting the text to lower in StartsWith as in Contains, and that might what make the issue. So if your check is case insensitive you can just use the following:
public void search_song()
{
for (int i = listbox_titles.Items.Count - 1; i >= 0; i--)
{
int char_count = listbox_titles.Items[i].ToString().Length;
if (listbox_titles.Items[i].ToString().IndexOf(txt_to_search.Text, StringComparison.OrdinalIgnoreCase) >= 0)
{
//listbox_titles.SetSelected(i, true);
MessageBox.Show(listbox_titles.Items[i].ToString());
}
}
Make sure your code isn't like your original when you do get it working because you will always get the message box:
if (listbox_titles.Items[i].ToString().ToLower().Contains(txt_to_search.Text) ||
listbox_titles.Items[i].ToString().StartsWith(txt_to_search.Text, StringComparison.Ordinal) ||
listbox_titles.Items[i].ToString().ToLower().Substring(0, char_count).Contains(txt_to_search.Text)
) ;
{
//listbox_titles.SetSelected(i, true);
MessageBox.Show(listbox_titles.Items[i].ToString());
}
That green squiggle on the syntax highlighter is pointing you to a warning that it is an empty statement - you have a semi-colon at the end of the if, so your block of code is not conditional at all.
Edit:
public void search_song(string txt_to_search)
{
foreach(var t in listbox_titles.Items)
{
String s = t.ToString().ToLower();
if(s.Contains(txt_to_search.ToLower()))
{
//listbox_titles.SetSelected(i, true);
MessageBox.Show(s);
}
}
}
This works for me because it keeps the size of the lines down to a manageable level - obviously, you would need to index using a variable rather than foreach.
Edit:
If you need to know where the occurrences are you can always define an extension helper:
public void search_song(string txt_to_search)
{
foreach (var t in listbox_titles.Items)
{
if(txt_to_search.Occurrences(t.ToString(), false).Count > 0)
MessageBox.Show(t.ToString());
}
}
}
static class StringHelpers
{
public static List<int> Occurrences(this string pattern, string source, bool caseSensitive = true)
{
List<int> occurs = new List<int>();
if (String.IsNullOrEmpty(pattern) || String.IsNullOrWhiteSpace(pattern))
return occurs;
int index = 0;
if (!caseSensitive)
{
pattern = pattern.ToLower();
source = source.ToLower();
}
while (index < source.Length) // was (index < source.Length - 1)
{
if ((index = source.IndexOf(pattern, index)) < 0)
break;
occurs.Add(index);
++index;
}
return occurs;
}
}
Just capture the list and interrogate it.
Edit: just noticed that I had the scan stop short of the end (no idea why, old age brain fade perhaps). It probably won't make a major difference unless you are searching for single characters (which is what I happened to do!)

Not all code paths return a value c#

I have declared a method in a class to compare two numbers and I'm having an issue. I'm getting an error saying not all code paths return a value. I want to return an int for every matching number in the char arrays.
Here is an image of the code.
public int CompareCodes(string rndselect, string personselect)
{
char[] rndnumber = rndselect.ToCharArray(); //take the randoms elected one and convert it to a char array
char[] perNum = personselect.ToCharArray();
likeness0 = 0;
likeness1 = 1;
foreach (char RndNum in rndnumber)
{
foreach (char Pnum in perNum)
{
if (RndNum == Pnum)
{
return likeness1;
}
else
{
return likeness0;
}
}
}
}
What should compiler think if your perNum is empty?
The error says exactly what is wrong with your code. Having a foreach loop doesn't guarantee anything inside the foreach is executed. If rndnumber or perNum happens to be empty, there is nothing to loop through and your code actually doesn't return anything.
If rndselect or perNum is empty string.
So no value is returned.
If you sure these string are always not null. so add
return 0
at the end of block.

C#... Not all code paths return a value

I am trying to create a Collection with properties and their respective accessors.
Here is my code:
class SongCollection : List<Song>
{
private string playedCount;
private int totalLength;
public string PlayedCount
{
get
{
foreach (Song s in this)
{
if (s.TimesPlayed > 0)
{
return s.ToString();
}
}
}
}
public int TotalLength
{
get
{
foreach (Song s in this)
{
int total = 0;
total += s.LengthInSeconds;
}
return total;
}
}
}
I'm receiving the error at the "get" point. It tells me that not all code paths return a value... What exactly does this mean, and what am I missing?
Firstly, the reason you're getting that message is that if this is empty, then the code within the foreach block (which is where the required return statement is) would never be executed.
However, your TotalLength() function would always return the length of the first Song, as you're declaring your variable, setting its value, then returning it within the foreach block. Instead, you'd need to do something like this:
int totalLength = 0;
foreach(Song s in this)
{
total += s.LengthInSeconds;
}
return totalLength;
Your PlayedCount function suffers from similar issues (if the collection is empty or contains no elements whose TimesPlayed property is greater than 0, then there would be no way for it to return a value), so judging by your comment you could write it this way:
public int PlayedCount()
{
int total = 0;
foreach(Song s in this)
{
if (s.TimesPlayed > 0)
{
total++;
}
}
return total;
}
It means just as it says, not all code paths return a value.
In this case, if your list is empty, then it cannot call return. In a foreach, there must be at least one item for the code to execute. Now, maybe you know that the list will always contain a value, but the compiler can't know that
What would your method return if this did not evaluate?
if (s.TimesPlayed > 0)
{
return s.ToString();
}
try using an else to return an empty string or something
The fact that 'this' could have no songs- in that case the loops will not execute at all and there is no implicit return value in C#.
Furthermore, your getters don't really make sense unless you only ever had one song in the collection. You need something more like this:
public int TotalLength()
{
get
{
int total = 0;
foreach (Song s in this)
{
total += s.LengthInSeconds;
}
return total;
}
}
Finally, without knowing how you keep track of TimesPlayed for each individual song, I wouldn't know how to implement that getter, but I am sure you can figure it out with this much.

Categories

Resources