-
String Comparsion
Code:
int main()
{
char strngs[100][20]={"BILL","BILL","BILL","JACK","JACK","KEN"};
checkDouble(strngs,6);
}
void checkDouble(char array[100][20], int len)
{
int i=0;
static int cnt = 0;
if(strcmp(array[i],array[++i]))
{
++cnt;
cout<<"There are "<<cnt << " "<<array[i];
checkDouble(array,--len)
}
else
cnt = 0;
}
i have created a test string called strngs.
strngs have 6 index.
i want to pass it to checkDouble so it will print something like this
There are 3 BILL
There are 2 JACK
There are 1 KEN
i know my recursion checkDouble is not correct and i dont know how to code this function.
can i get some help.
thanks.
-
Do you need to use recursion?
You can't print a message every time you increment cnt, or you'll get something like
Code:
There are 1 BILL
There are 2 BILL
There are 3 BILL
. . . assuming the rest of the code works properly. Which it won't.
Code:
if(strcmp(array[i],array[++i]))
I'm pretty sure that's undefined behaviour, and you probably want ==0 anyway.
Code:
char strngs[100][20]={"BILL","BILL","BILL","JACK","JACK","KEN"};
This works as well, and you save a lot of space.
Code:
char *strngs[100]={"BILL","BILL","BILL","JACK","JACK","KEN"};
You just can't modify the strings, that's all.
I think you need to re-think the logic behind your code. How would you determine duplicates? Maybe start with the first name, search for the strings that match it, and then continue on with the second name, and so on. You'd have to set a string to "" or something once you counted it, or you'd count every string more than you wanted to.
-
Code:
#include <iostream>
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
void checkDouble(char array[100][20], int len);
int main()
{
char strngs[100][20]={"BILL","BILL","BILL","JACK","JACK","KEN","KEN","MILO"};
checkDouble(strngs,8);
}
void checkDouble(char array[100][20], int len)
{
cout<<"Passed array ";
for (int n = 0; n <len; n++)
{
cout<<array[n]<<" ";
}
cout <<endl;
int cnt = 0;
for (int i =0; i <len; i++)
{
for (int j = ++i; j<len; j++)
{
if (strcmp(array[i],array[j]))
++cnt;
}
cout<<array[i]<<" "<<cnt<<endl;
cnt =1;
}
}
somehow this work when i use only 6 strings
for example
{"BILL","BILL","BILL","JACK","JACK","KEN"};
i would get
BILL 3
JACK 2
KEN 1
but when i pass
{"BILL","BILL","BILL","JACK","JACK","KEN","KEN","M ILO};
i would get
BILL 5
JACK 4
KEN 2
MILO 1
that is not right.
what else i need to do.
-
Perhaps you'd want to do this:
Code:
for (int j = i+1; j<len; j++)
That way, you don't increment "i" outside of your loop.
--
Mats
-
when i do that i get
BILL 5
BILL 6
BILL 6
JACK 4
JACK 4
KEN 2
KEN 2
MILO 1
-
Quote:
Originally Posted by
nicz888
Code:
int cnt = 0;
for (int i =0; i <len; i++)
{
for (int j = ++i; j<len; j++)
{
if (strcmp(array[i],array[j]))
++cnt;
}
cout<<array[i]<<" "<<cnt<<endl;
cnt =1;
}
}
1. The variable i is going up by two each time (one increment in the for loop on i, one increment in the for loop on j), so the comparisons are occuring on elements number 1, 3, 5, 7, etc....
2. Notice that strcmp returns 0 when the strings are equal, so you're actually finding the number of strings that don't match after the start (sort of, see ...)
3. You should decide whether cnt needs to start at 0 or at 1.
-
i change it to this
Code:
int cnt = 1;
for (int i =0; i <len; i++)
{
for (int j = i+1; j<len; j++)
{
if (!strcmp(array[i],array[j]))
++cnt;
}
cout<<array[i]<<" "<<cnt<<endl;
cnt =1;
}
}
my output is
BILL 3
BILL 2
BILL 1
JACK 2
JACK 1
KEN 1
KEN 2
MILO 1
now how do i prints the same name and count just once.
-
And how do you think you should work around the problem that once you've counted the number of BILL, you count BILL's again (but with one less to count, so you end up with 2 instead of three. [Which is really easy if they are nicely in bunched together, but if the list is "BILL", "JOHN", "BILL", "TOM", "BILL" you may have a bit more of a challenge].
--
Mats
-
>>void checkDouble(char array[100][20], int len)
Correct me if I'm wrong, but I'm pretty sure that you can't do that. You have to have one of the parameters as a char*.
A vector of strings would be much easier...
-
> Correct me if I'm wrong
The syntax is fine.
If you want a * in there, it would be
void checkDouble(char (*array)[20], int len)
This also works
void checkDouble(char array[ ][20], int len)
What it isn't is either of these:
void checkDouble(char **array, int len)
void checkDouble(char *array[20], int len)
Whilst it's possible to have functions declared like that, neither is suitable for passing a 2D array to. Arrays of pointers perhaps, but not arrays of arrays.
-
But this is C++, so why use chars and not std::string (and maybe std::vector)?
But also for your error, you realize that this is an implementation problem, and not a bug, yes?
You see, there are two problems - first, if there's a duplicate, like Bill in index 0 and 1, then Bill will be checked for duplicates more than once.
And two, you are only searching from i + 1, so you aren't checking the entire array again for duplicates. This one may be a bug. You want to check from the beginning and skip checking the index you're comparing to (i), since it would give you a duplicate.