deleted

Hi, I am beginner in C++ and I'm trying to figure out how to create a program to check if different words in a strings has the exact same alphabetic characters and find their location.

(Ignoring spaces and any non-alphabetic character)
Also, it doesn't matter if the char is lower or upper as long as it's the same char.

*words are separate by a commas then a space.


deleted
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <cctype>
using namespace std;

int main()
{
	string str1("Foru m");		//inserted spaces
	string str2("Mr uo f");


//// FIRST APPROACH

	//remove space and non alphanumeric
	for(int i = 0; i < str1.size(); i++)
		if(!isalnum(str1.at(i)))
			str1.erase(str1.begin() + i);
		else
			str1.at(i) = tolower(str1.at(i));	//convert interested characters to lower case

	//copy paste
	//remove space and non alphanumeric
	for(int i = 0; i < str2.size(); i++)
		if(!isalnum(str2.at(i)))
			str2.erase(str2.begin() + i);
		else
			str2.at(i) = tolower(str2.at(i));	//convert interested characters to lower case

	//sort strings
	sort(str1.begin(),str1.end());
	sort(str2.begin(),str2.end());

	cout<<boolalpha<<(str1 == str2)<<endl<<endl;

//// SECOND APPROACH ////
	string s1("Foru m");
	string s2("Mr uo f");

	int a = 0;	//counts
	int b = 0;

	for(int i = 0; i < s1.length(); i++)
		if(isalnum(s1.at(i)))
			a += tolower(s1.at(i));
	for(int i = 0; i < s2.length(); i++)
		if(isalnum(s2.at(i)))
			b += tolower(s2.at(i));
	
	cout<<boolalpha<<(a == b)<<endl<<endl;

	system("pause");
	return 0;
}
Last edited on
The second approach suggested will not always work for all strings. For example:
xz and yy

You should also be checking for isalpha not isalnum
Last edited on
Why do you say it will not work for xy and yy.
Tested with those and program gives me false in both cases. Which is ofcouse the expected result.
I have updated the code in the first post using ShadowCODE's first approach.
However there's an error whenever I put a space or a non-alpabetic into one of the strings to compare..
(note that the main is in a separate file)
Last edited on
Ok. made the following changes to your code.
First , the prototype in line 5
bool HaveSameChar(const char * const s1, int n1, const char * const s2, int n2)
Its supposed to be
bool HaveSameChar(const char * s1, int n1, const char *s2, int n2)
If you keep s1 and s2 as const, then you cant increment them as you did in lines 14 and 18.

Also in the for loops at line 21 and 28, use temp.length() and temp2.length() respectively since we are now dealing with temp and temp2 instead of s1 and s2.

Also in the body of those loops, you should decrement i after erasing.
So you should have
1
2
3
4
5
if (!isalpha(temp.at(i)))
{
    temp.erase(temp.begin() + i);
    i--;  //this will check that position again
}//do same for temp2 
Another approach using standard library and C++11 features:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <cctype>
#include <algorithm>

//transforms string to ordered set of characters for easy compare
std::string normalize(std::string s)
{
    //Erase all not-alphabet character
    s.erase(std::remove_if(s.begin(), s.end(), [](char c)
                                                  { return !isalpha(c);}),
            s.end());
    //Make all character lowercase
    std::transform(s.begin(), s.end(), s.begin(), ::tolower);
    //Sort characters
    std::sort(s.begin(), s.end());
    return s;
}

bool are_same(const std::string& lhs, const std::string& rhs)
{
    //Comparing two sets of characters
    return normalize(lhs) == normalize(rhs);
}


int main()
{
    std::cout.setf(std::ios::boolalpha);
    std::cout << are_same("Forum", "Mruof") << '\n' <<
                 are_same("C plus PLUS ++", "LUSpclusP") << '\n' <<
                 are_same("then", "than") << '\n';
}
true
true
false
shadowCode wrote:
Why do you say it will not work for xy and yy.
Because it is not working properly: http://ideone.com/w8Bcl1
Last edited on
I just figured those a couple minutes after posting haha. Thanks a lots! Your code helped me a lots.

I also have another question if you have time on you.

Would you know a way to find the number of same anagram (or sentence with same char) in a long string with multiple word?

ex: TheInput = " Forum, I'm a beginner ++, RumFo, begiN aER Mi, KOBO, book, MUR FO"

Result : out[0]= 0, 4, 7 (location of the 3 word with "forum" chars)
out[1]= 2, 3 ( 2 words with "imabeginner" chars)
out [2] = 5,6 ( 2 words with "book" chars)

*more details in first post

deleted
Last edited on
1) Separate string into words:
1
2
3
4
5
std::vector<std::string> words;
std::istringstream in(TheInput);
std::string s;
while(std::getline(in, s, ',')) //separates string into tokens separated by comma
    words.push_back(s);


2) loop on vector of words and check for annagrams, insert index in out vector if needed.

(Are your example result correct? I cannot understand how they were calculated)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
using namespace std;

string normalize(std::string s)
{
    //Erase all not-alphabet character
    s.erase(std::remove_if(s.begin(), s.end(), [](char c)
                                                  { return !isalpha(c);}),
            s.end());
    //Make all character lowercase
    std::transform(s.begin(), s.end(), s.begin(), ::tolower);
    //Sort characters
    std::sort(s.begin(), s.end());
    return s;
}
int main()
{
	string inputString("Forum, I'm a beginner ++, RumFo, begiNN aER Mi, KOBO, book, MUR FO");
	stringstream ss;
	vector<string> vec;

	ss<<inputString;
	string s;
	while(getline(ss,s,','))
		vec.push_back(s);
	
	//normallize with MiiNiPaa's function
	for(int i = 0; i < vec.size(); i++)
		vec.at(i) = normalize(vec.at(i));
	
	cout<<"Words are "<<endl<<"----------"<<endl;
	for(int i = 0; i < vec.size(); i++)
		cout<<vec.at(i)<<"  ";
	cout<<endl;

	vector<vector<string>> out;  //2D
	for(int i = 0 ; i < vec.size(); i++)
	{
		vector<string> temp;
		temp.push_back(vec.at(i));
		vec.erase(vec.begin() + i);
		i--;

		for(int j = i+1; j < vec.size(); j++)
		{
			if(temp.at(0) == vec.at(j))
			{
				temp.push_back(vec.at(j));
				vec.erase(vec.begin() + j);
				j--;
			}
		}
		out.push_back(temp);
	}

	cout<<endl<<"Anagrams are "<<endl<<"---------"<<endl;
	for(int i = 0; i < out.size(); i++)
	{
		for(int j = 0; j < out.at(i).size(); j++)
		{
			cout<<out.at(i).at(j)<<" ";
		}
		cout<<" - "<<out.at(i).size();
		cout<<endl;
	}
	cout<<endl;
	system("pause");
	return 0;
}
@MiiNiPaa The second approach of the firs problem works fine on ma machine and in on these 2 websites.

http://ideone.com/hI07g7

http://codingground.tutorialspoint.com:6639/index.htm?SESSIONID=7ul8jcqiesl2hntn4qb46phpk5

Last edited on
No, it is not working for all strings. Look at my ideone link.
It is not working properly for xz and yy atrings, for example.
Oh i see. Thanks
How
Last edited on
Topic archived. No new replies allowed.