I'm tring to solve a small problem. I have two strings. s1 and s2. I want my function to return the first index of s1 that has a character not present in the string s2. This is my code.
int cad_nenhum_dos (char s1[], char s2[]){
int i,j;
for (i=0;s1[i]!='\0';i++)
{
for (j=0;s2[j]!='\0';j++)
if (s1[i]!=s2[j]) return i;
}
return -1;
}
If I run s1="hello" s2="hellm", the result should be index 4, because s1[4]='o' and "o" is not present in s2... But I allways get 0 when I run this. The -1 works fine if the strings are the same.
What am I doing wrong?
Regards
In your inner loop you need to break out when you find a character the same -- as it stands you're returning when there are any different characters in the second string, even if an earlier one was the same. You want something like
for (j=0;s2[j]!='\0';j++)
if (s1[i]==s2[j]) break;
if (s2[j]==0)
return i;
I.e. you want to return the ith character of the first string when you've made you way through the whole of the second string without having found that character.
For programming exercises at the introductory level it's a good idea to carefully execute the code manually (step through yourself and see what's happening).
As TooTone suggested, you need to break out of the loop when you find a match:
for (int i = 0; s1[i] != '\0'; i++)
{
bool charFound = false;
for (int j = 0; s2[j] != '\0'; j++)
{
if (s1[i] == s2[j])
{
charFound = true;
break;
}
}
if ( ! charFound)
return i;
}
Because the inner for-loop is comparing first letter of the first string against all the letters in the second string.
int cad_nenhum_dos (char s1[], char s2[])
{
int i,j;
for(i=0; s1[i]; i++)
{
if(s1[i] != s2[j])
return(i);
}
return(-1);
}
Related
Let's say I have a function
int pozvec(vector<string> vect)
which takes as parameter a pre-filled vector of strings.
I want to know at which position i there is the character "p", specifically "p". All of the strings are single-character, but the vector is declared as containing strings. I want to save the index at which "p" is found in a variable x;
for(int i=0; i<vect.size(); i++)
if(vect[i] == "p")
x=i;
does not seem to work. Nor does strcmp, at all.
The problem is more complex, but the part that doesn't work is this one.
Thank you in advance for your help!
I don't know what you really want to do, but this worked perfectly fine for me:
for (size_t i {}; i < vec.size(); ++i) {
if (vec.at(i) == "p") {
x = i;
break; // I don't know wether you want to break here or not
} else {
continue;
}
}
Or if you all strings include just one character this should also work:
for (size_t i {}; i < vec.size(); ++i) {
if (vec.at(i).at(0) == 'p') {
x = i;
break; // I don't know wether you want to break here or not
} else {
continue;
}
}
By that function, your storing the index of the last occurrence of the string your looking for. This is because your not exiting from the loop once the first occurrence was found.
To exit from a loop conditionally, use the break statement.
for(int i = 0; i< vect.size(); i++)
{
if(vect[i] == "p")
{
x=i;
break;
}
}
Now it will exit right after the first occurrence was found.
You also have another option in the form of std::find.
int index = std::find(vect.begin(), vect.end(), "P") - vect.begin()
I am trying to compare two string arrays, but am not allowed to use classes or libraries to assist.
The issue I have with this is that if one string is more than one character, then it compares the whole string to again, even though it already checked the first one.
char *find_first_not_in_the_set(char *str, const char *set)
{
for(int i = 0; *(str + i) != '\0'; i++)
{
for(int j = 0; *(set + j) != '\0'; j++)
{
if(str[i] != set[j])
{
return &(str[i]);
}
}
}
return NULL;
}
If "Hello World!" is the first string and the second string is "He". The program should return l, but it returns H because it still checks the first character.
I'd rather use this:
bool matrix[256] = {0};
int length = strlen(set);
// remember all characters we have in the 'set'
for( int i=0; i<length; i++) matrix[set[i] & 0xFF] = 1;
length = strlen(str);
// now check the characters from 'str'
for( int i=0; i<length; i++) {
if( ! matrix[str[i] & 0xFF] ) {
printf( "Found: %c", str[i] );
break;
}
}
For every character in str, your code checks if it is present on each and every position in set.Thus, when i=0 'H' is compared with set[0] i.e. 'H' for j=0.But when j=1,'H' is compared with 'e' and this causes the function to return str[0] because i is still 0.
Your problem will be solved if you use just one loop and check str[i]!=set[i].
I am attempting to add space before a character in a string by using the insert function.
Can someone kindly explain why the following code does not work ?
for(int i = 0; i < line.length(); i++)
{
if(line[i+1] == '=')
{
line.insert(i, " ");
}
}
If you want to insert before = you can get the index of = directly and not the index of char followed by =. This could lead to out of bounds access.
Also, when you insert the space you extend your string by 1, that's ok but only if you also adjust the counter i, otherwise it will insert again and again and again before = resulting in infinite loop. Adjust your code in this manner:
for (int i = 0; i < line.length(); i++)
{
if (line[i] == '=')
{
line.insert(i++, " ");
}
}
The code seems fine except for one little detail:
Imagine you have a string with "test=something". When you iterate it, when i is 3 you will find the next character is an equals, so you put a space into it. Next iteration i will be 4, but you just added a space, so at i equals 5 there's the same equals sign. So you put another space and so on. TO fix this youy can try:
std::string line = "test=something";
for (int i = 0; i < line.length(); i++)
{
if (line[i + 1] == '=')
{
i++;
line.insert(i, " ");
}
}
In the method below, I have a two-dimensional array of characters called myarr and a string called code. I go through each character in code using the counter i, and look for a character in myarr that matches code[i]. When I find the character in myarr that matches code[i], I want to exit both of the for loops and the if statement and go back to the beginning of the while loop. The only way I can think of doing this is by using a goto statement. However, using goto is generally discouraged, so I was wondering if there was any other way to achieve this.
string decrypt(string code, char myarr[][5])
{
int r = 0;
int c = 0;
int i = 0;
string newstr = "";
while(i<code.length()-1)
{
//This is where I want to go back to
if (code[i] != ' ')
{
for (r = 0; r < 4; r++)
{
for (c = 0; c < 4; c++)
{
if (code[i] = myarr[r][c])
{
newstr += myarr[c][r];
i++;
//This is where I want to exit
}
}
}
}
else
{
newstr += " ";
i++;
}
}
return newstr;
}
You use a flag-ish variabele.
set a boolean to true at the beginning of the while loop.
then when the condition is met, you set it to false.
in every inner loop you also check for that flag being true.
Also. in my opinion this is one of the cases where goto is justified.
What I'd do:
char decrypthelper(char codech, // returns the substitution character for codech
const char myarr[][5]) //const because we aren't changing myarr.
// This will make sure we don't, and maybe
// the compiler can do something sneaky.
{
if (codech != ' ')
{
for (int r = 0; r < 5; r++) // fixed off by one error
// declare index variable here. No one else needs it
{
for (int c = 0; c < 5; c++) // fixed off by one error
{
if (codech == myarr[r][c]) // was assignment not compare
{
return myarr[c][r]; // found substitution. Exit
}
}
}
}
else
{
return ' '; // space... the final frontier
}
return '?'; // unknown character
}
string decrypt(string code, char myarr[][5])
{
string newstr = "";
for (auto codech: code) // for each character in code
{
newstr += decrypthelper(codech, myarr); // add substitution character
}
return newstr;
}
I tried to keep the code recognizable. There are a whole bunch of other tricks you can use to make your job a lot easier, so once you have your program up and running and bug free, take Quentin's suggestion about asking for a code review.
Note that many returns in a function is viewed in some circles as just as bad as goto.
As others have mentioned you can use a flag-ish variable. You can also use an exception as a way to break out of multiple loops.
You can also put the two inner loops into a separate function and use return.
But looking at the code why not change the algorithm? You should create a map from char to decrypted char so you can simply use:
newstr += map[code[i]];
Write a function receives a string and a character which is to be searched in the string. This function function returns the index of the search character if it exists in the array, or -1 if it does not. Also if the array contains more than one occurrence of the character, it returns the index of the left-most occurrence. For instance, if the string was ”abab” and the search character was ’b’, the function returns 1; whereas if the character was ’c’, the function returns -1.
Write the function WITHOUT using any C++ library functions.
Below is my function.
int indexOf(const char str[], char ch)
{
int search;
for (int i = 0; i<20; i++)
{
if (ch = str[i])
search ==i;
else
search =-1;
}
return search;
}
My problem is I keep getting 19(20-1) when I input either the search character or the character that doesn't exist in the array. Could anyone tell me how to modify my code to get the right answer?
if (ch = str[i]) should be if (ch == str[i]), at the moment you're just doing an assignment to ch.
And search ==i is doing a comparison, it should be search = i; so it's the opposite issue of the first.
The way I would do it is:
int indexOf(const char str[], int size, char ch)
{
for (int i = 0; i<size; i++)
{
if (str[i] == '\0')
return -1;
else if(str[i] == ch)
return i;
}
return -1;
}
The approach has the advantage of not wasting time searching in the rest of the string when it was already discovered before.
You did some mistakes. if (ch = str[i]) should be if (ch == str[i]) and search ==i; should be search =i;
And, no need to use the size of the arr if you pass a null-terminated strings.
You can try like this.
int indexOf(const char str[], char ch)
{
for (int idx = 0; str[idx]; idx++)
{
if (str[idx] == ch)
return idx;
}
return -1;
}