How to see if two strings have the same characters in it?

Hey, I want to see if my two strings have the same characters in it but in different orders. So here’s an example: crisps and rcips have the same characters in it but the characters are in different orders, if you know how I would do that please let me know. Thanks.

Several ways to do this, but let me ask about some edge cases first:

  • Will the strings always have the same length?
  • Do you know if letters can appear more than once in a single string?
  • If letters can appear more than once in one string, must they appear the same number of times in the other string to be considered the same?

Based on your example, the answers should be “no,” “yes,” and “no.” If so, this might do it:

public bool Same(string s1, string s2)
{
    bool isSame = true;
  
    for (int i1 = 0; i1 < s1.Length; ++i1)
    {
        int i2;
      
        for (i2 = 0; i2 < s2.Length; ++i2)
        {
            if (s1[i1] == s2[i2])
            {
                break;
            }
        }
      
        if (i2 == s2.Length)
        {
            isSame = false;
            break;
        }
    }
  
    return isSame;
}

Hope we get an “A” :roll_eyes:.

1 Like

Based on your example, i assume that they dont have to contain the same amount of characters, just the same overall.
As Stevens said, there are a lot of ways to approach this. Just to list one:

  • Let’s name one of the strings “main” and the other “other”
  • Look at mains first character c
  • Check if other.Contains(c). If it does not you are done and the condition is not fulfilled
  • If it does, remove (all) c from both main and other
  • Repeat 2 to 4 until main is empty
  • Reaching this step, the condition is fulfilled if other.IsEmpty(), otherwise not.

For removing characters from a string you can use the Replace function and just replace them with an empty string.

2 Likes

That’s pretty slick. Crafty way to insure the first character in main is always the next one you need to consider, with no redundancy.

Another approach would be to sort the characters within the strings alphabetically (LINQ should be able to do it). Then you can check if the shorter string is contained in the longer one. So your example would give:
ciprss and
ciprs
The second one is contained in the first. But if you had a double i instead of a double s it would not work anymore. So it highly depends on the properties your input strings will have, like Stevens-R-Miller already stated.

If the conditions included that no character appears more than once, this works immediately. The duplicates could be eliminated however, so that an input string of “cartoonist” would sort to “acinoorstt,” then reduce to “acinorst.” A candidate matching string of “isonacart” would sort to “aacinorst,” which also reduces to “acinorst,” which matches the reduced sorted version of the first string.

If my memory serves, that second step is called a “homomorphic mapping,” but I could be wrong about that.

Hey, sry if I’m dumb but how would I implement that into my code. Sry if I ask to much but here’s my code:

        if (maxClicks <= 0) {
            if (curPressedPattern == pattern ) {
                touchBool = true;
                if (Object.transform.position.y < maxYaxis.y) {
                    if (touchBool == true) {
                        Object.transform.position += transform.up * speed * Time.deltaTime;
                    }
                } else {
                    touchBool = false;
                }
                Debug.Log("You got right");
            } else {
                curPressedPattern = nothing;
                StartCoroutine(timer());
            }
        }

Thanks, again.

Maybe I’m the dumb one, but I’m having a hard time seeing how any of that code relates to strings.

2 Likes

Oh, my fault I didn’t comment where the strings where. Sorry if I’m wasting your time but here’s the commented code:

    if (maxClicks <= 0) {
                if (curPressedPattern == pattern ) { // Those variables were strings btw. So instead of checking if the strings have the same characters in the same order, I want to make it so if the strings have the same characters but in different orders it will still be true (the if statement).
                    touchBool = true;
                    if (Object.transform.position.y < maxYaxis.y) {
                        if (touchBool == true) {
                            Object.transform.position += transform.up * speed * Time.deltaTime;
                        }
                    } else {
                        touchBool = false;
                    }
                    Debug.Log("You got right");
                } else {
                    curPressedPattern = nothing;
                    StartCoroutine(timer());
                }
            }

Thanks.

I lol’d at that.

Currently you just compare the string patterns via equality operator. People have gave you some ideas on how to approach it but you have not implemented it. So where specifically is the problem? Or is this just a scheme to “trick” someone else into writing your code?
Also you did not further specify the properties the strings can have. Guessing is bad thing to base suggestions on. If you declare the rules after which the string patterns are built we could suggest one method over the other.
Or in general it could be usefull to know what you are trying to achieve with this at all (high altitude view).

1 Like

Since these are short strings (less than a thousand characters) and only checked infrequently, a wasteful but obvious solution might be best. Check if every letter in the 1st is in the second, then if every in the second is in the 1st (for cases like “abc” and “abcd”):

bool _isFirstInSecond(string checkMe, string allTheLetters) {
  foreach(char ch in checkMe)
    if(!allTheLetters.contains(ch)) return false;
  return true;
}

bool bothHaveSameChars(string w1, string w2) {
  return _isFirstInSecond(w1, w2) && _isFirstInSecond(w2,w1);
}

It’s the kind of complete garbage solution that many people start with, it works fine, and they never bother replacing it with a good one.

Oh,crap. I fixed it, I was just a little dumb and didn’t know how to implement it into my code, I guess I was just tired. I’m so sorry that I wasted your guys time. But yeah, sometimes you’re just tired.

I’ll take an easy-to-understand “garbage” solution over a what-the-eff-is-this-doing? “elegant” one, every time.

1 Like

But in this case “sort, remove duplicates, check for equality” is the textbook solution and is easy to see it’s correct. Except sort probably requires converting into a char-array, and I don’t know the “remove duplicates” command off the top of my head and it probably requires an extra “counts as the same” function, plus it probably requires a List, not an array.

So many elegant solutions require extra scaffolding, and when I use a command I haven’t used 10 times before I usually screw it up.

Hey, I used the code but I got this error: error CS1061: 'string' does not contain a definition for 'contains' and no accessible extension method 'contains' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) and btw here’s the code I used:

    bool _isFirstInSecond(string checkMe, string allTheLetters) {
    checkMe = curPressedPattern;
    allTheLetters = pattern;
    foreach(char ch in checkMe)
        if(!allTheLetters.contains(ch)) {
            return false;
        }
      return true;
    }
    
    bool bothHaveSameChars(string w1, string w2) {
      return _isFirstInSecond(w1, w2) && _isFirstInSecond(w2,w1);
    }

thanks, I’m kinda new to this programming thing.

We all were, once, so your problems are easy to relate to.

However, you must quickly get past being new to reading the manual. All of the C# classes have excellent documentation online, which you can read for free. For example, you can see the full details on the string class’s Contains method here. Note that it starts with a capital letter. In C#, case matters.

There is also a fine tutorial you can follow that will help you quickly get over these basic kinds of errors. It’s well worth your time.

The OP’s last bit of code is manually replacing parameters with globals inside a function. That doesn’t even make any sense. You’d only do that if you didn’t know what functions are. I think an old “how can I learn programming” thread might be more helpful. Everything here is way past their ability.

2 Likes

Ok, I will check that out. Idk why but when I fixed the last error and then another error appeared, that I don’t know how to fix. I know I should look at a manual, but I did. It’s something that it needs to be a string value or something. The error is: error CS1503: Argument 1: cannot convert from 'char' to 'string'. I have the same code as before but with capital letter on contains.

Whoops, I didn’t even realize we had switched beginners. kucid isn’t the OP, or else isn’t the same account the OP first used.

I am going to step back here and agree with the following:

These forums are a great place for Unity programmers, both new and old, to seek help. ImGundulf and kucid are having the kinds of problems all new programmers have, and we all know those can be frustrating. However, asking for help on them here is not a good way to learn basics. Following any of the many, many good tutorials available for free on the internet (or even some of the ones that are not for free, including taking classes) would be a far better way for our friends here to learn how to code.

kucid, your most recent error has to do with the fact that your are dealing with two different types of data. This is one of the most fundamental aspects of dealing with C#. Absolutely any introductory book on programming in C# will cover this at the start. (For example, it is addressed on page 21 of “C# 7.0 in a Nutshell.” Although the book calls itself a “nutshell,” it is over 1,000 pages long. The fact that types are covered on page 21 tells you something about how basic that topic is.)

Both of you, kucid and ImGundulf, would learn faster and have more fun if you paused the projects you are working on, and went to school instead. “School” can be w3schools.com, a book, videos on YouTube, or any other way you find works for you as you learn the basics. When you’ve done that and need help you can’t find that way, come back. We’ll be here.

2 Likes