0
#include <iostream>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <cstdio>

using namespace std;

static bool isanagram(string a, string b);

int main(void)
{
    int i,n,j,s;
    cin >> n;
    string a, b;
    cin >> a >> b;
    if(!isanagram(a,b)) cout << "False" << endl;
    else cout << "True" << endl;
    return 0;


}

static bool isanagram(string a, string b)
{
    int i, j, size, s=0;
    size = a.size();
    bool k;
    for(i=0;i<size;i++)
    {
        k=false;
        for(j=0;j<size;j++)
        {
            if(a[i] == b[j]) { k = true; break; }
        }
        if(k==true) s+=1;
    }
    cout << a[2] << b[2] << endl;
    if(s == size) return true;
    else return false;

}

I don't know where exactly is the problem so i just pasted the whole code.

It should be a simple program capable for finding if two strings are anagrams, but it's not working and i don't know why. I used pointers in the program so thought the might be the problem and removed them, i removed other things additionally but still it's not working. If you can give it a look-see and tell me some idea where i might've gone wrong with my code ?

Thank you in advance.

ggg
  • 937
  • 5
  • 13
  • 16
  • People might answer if you accepted more answers than you have so far. – Oded Feb 09 '10 at 15:54
  • 2
    btw, your code may crash if the the second string is shorter than the first one. – erelender Feb 09 '10 at 15:57
  • 1
    It's the figure which in your case is 0%, meaning you didn't accept any of the answers you've had to all your previous questions. – Paul R Feb 09 '10 at 15:58
  • 3
    @ggg: This is your 9th question. You have not accepted any of the answers given to the other 8. – dave4420 Feb 09 '10 at 15:58
  • the string are supposed to be equal in size. – ggg Feb 09 '10 at 15:59
  • 2
    It also will not return the true answer if the first string contains two of the same character but the second string contains only one of that character. – erelender Feb 09 '10 at 16:01
  • 1
    You should pass std::string by const reference http://stackoverflow.com/questions/1885785/passing-c-strings-by-value-or-by-reference. – Manuel Feb 09 '10 at 16:09

6 Answers6

3

It's not always return true:

Here's my input:

0
sdf 
fda

Here's output I got:

fa 
False

Regarding your task: if performance is not an issue for you task, just sort 2 strings (using std::sort) and compare results.

Regarding your style:

  • use string::length() instead of size() -- it's more idiomatic
  • instead of if(s == size) return true; else return false; consider return s == size
  • pass your strings by const reference, not by value
  • consider declaring variables as close to point of their usage as possible (but not closely) and initialize them when declaring (i, j, k, size all fit this hint)
Alexander Poluektov
  • 7,844
  • 1
  • 28
  • 32
3

The logic for your isanagram function is fatally flawed - it will never work correctly, even if you manage to fix the bugs in it.

You need to make sure that you have a correct algorithm before you start coding. One simple algorithm might be:

  • sort a
  • sort b
  • isanagram = (a == b)
Paul R
  • 208,748
  • 37
  • 389
  • 560
2

There are essentially two ways of checking for anagrams:

  1. Sort both strings and see if they match. If they are anagrams, they will both have the same letters and a sort would order them into the same sequence.

  2. Count the frequency of each char in each string. If they are anagrams, the frequency counts for each char will be the same for both strings.

MAK
  • 26,140
  • 11
  • 55
  • 86
2

Your approach is fine but it has a small flaw. You ensuring that every char from string a is present in string. So if a = "aab" and b = "abc", your approach will flag them as anagram. You also need to take the count of char in account.

The definition of anagram is:

An anagram is a type of word play, the result of rearranging the letters of a word or phrase to produce a new word or phrase, using all the original letters exactly once;

Easiest way as many have suggested is to ensure that the strings are of the same length . If they are, sort the two string and check for equality.

If you want to patch your approach, you can make the char in string b NULL after it has been matched with a char in string a.

Something like:

if(a[i] == b[j]) { b[j] = 0; k = true; break; }

in place of your:

if(a[i] == b[j]) { k = true; break; }

This way once a char of b has been matched it cannot participate again.

codaddict
  • 445,704
  • 82
  • 492
  • 529
  • If two strings are the same before sorting, are they anagrams? The definition you cited says a *new word or phrase*, implying that the strings must be different before sorting. Also, spaces should probably be removed, but this depends on the requirements of the homework assignment. – Thomas Matthews Feb 09 '10 at 17:44
0

I see some problems with your code. Basically the algorithm is wrong. It will match characters within a.size(). It takes no account for duplicates (in either a or b).

Essentially, you should sort the strings and then compare for equality.

If you can't sort, at least remove the b characters from the comparison, eliminate the k variable.

Liz Albin
  • 1,479
  • 8
  • 8
0

First things first: don't declare the method static. It's a confusing keyword at the best of times given all the roles it can fulfill... so reserve for times when you really have to (method or attribute of a class that is not tied to any instance for example).

Regarding the algorithm: you're nearly there, but presence only is not sufficient, you need to take the number of characters in account too.

Let's do it simply:

bool anagram(std::string const& lhs, std::string const& rhs)
{
  if (lhs.size() != rhs.size()) return false; // does not cost much...

  std::vector<int> count(256, 0); // count of characters
  for (size_t i = 0, max = lhs.size(); i != max; ++i)
  {
    ++count[lhs[i]];
    --count[rhs[i]];
  }

  for (size_t i = 0, max = count.size(); i != max; ++i)
    if (count[i] != 0) return false;

  return true;
} // anagram

Let's see it at work: anagram("abc","cab")

  1. Initialization: count = [0, 0, ...., 0]
  2. First loop i == 0 > ['a': 1, 'c': -1]
  3. First loop i == 1 > ['a': 0, 'b': 1, 'c': -1]
  4. First loop i == 2 > ['a': 0, 'b': 0, 'c': 0 ]

And the second loop will pass without any problem.

Variants include maintaining 2 counts arrays (one for each strings) and then comparing them. It's slightly less efficient... does not really matter though.

int main(int argc, char* argv[])
{
  if (argc != 3) std::cout << "Usage: Program Word1 Word2" << std::endl;
  else std::cout << argv[1] << " and " << argv[2] << " are "
                 << (anagram(argv[1], argv[2]) ? "" : "not ")
                 << "anagrams" << std::endl;
}
Matthieu M.
  • 287,565
  • 48
  • 449
  • 722