Home > Net >  Comparing two arrays against each other to find a common charecter
Comparing two arrays against each other to find a common charecter

Time:03-09

    int main(){
    int x;
    const int Maxword = 5;
    char Guess[Maxword] {};
    std::string words[Maxword] = {
        "Hello",
        "World",
        "Shift",
        "Green",
        "Seven"
    };
    srand(time(NULL));
    int iSecret = rand() % Maxword;
    std::string Word(words[iSecret]);
    for (int i = 0; i < 5; i  ) {
        std::cout << Word[i] << std::endl;

    }
    for (int i = 0; i < 5; i  ) {
        std::cout << ("Please enter the letters you would like to guess") << std::endl;
        std::cin >> Guess[i];
        std::cout << Guess[i] << std::endl;
    }
    for (int i = 0; i < 5; i  ) {
        if (Guess[i] == Word[i]) {
            std::cout << Guess[i] << "\t" << "Is in the right place" << std::endl;
        } else if (Guess[i] != Word[i]) {
            std::cout << Guess[i] << "\t" << "Isnt in the right place" << std::endl;
        } else {

        }

    }
}

Here I have My code and I would like to compare the two character arrays Guess and Word to check for a common character how would I do this.

CodePudding user response:

According to your clarification in the comments, you want to have three kinds of output:

  1. the letter is in the word and guessed in the correct position
  2. the letter is in the word but guessed in the wrong position
  3. the letter is not in the word

Your current loop is handling only case #1.

To handle #2 (and by extension #3) you can use std::string::find. That function will return the position of the character in the string, or if not found it returns std::string::npos.

So, the logic could be:

if (Guess[i] == Word[i]) {
    std::cout << Guess[i] << "\tis in the right place\n";
} else if (Word.find(Guess[i]) != std::string::npos) {
    std::cout << Guess[i] << "\tisn't in the right place\n";
} else {
    std::cout << Guess[i] << "\tisn't in the word\n";
}

See the documentation for std::string::find

In C 23, there is a nicer way to test if the string contains a character: std::string::contains

As a closing comment, it's important that you understand the distinction between a string object and an array:

  • In your question and followup discussion, you keep referring to Word an array, but it is not -- it is a std::string. It overloads the operator[](size_t) so that you can use array syntax to access characters, but that does not make it an array.

  • The only arrays in your program are Guess (an array of char values) and words (an array of std::string values).

CodePudding user response:

I know this is strictly speaking not directly an answer to your question but I believe it might help you and others nevertheless.

Correct me if I am wrong but I believe what you are trying to do is to implement the game of Wordle.

Wordle with Map

While your approach with arrays would work I have implemented a different approach to implement the game using maps. Maps are well suited for quick lookups in constant time i. e. O(1) so they are generally faster than searching in arrays and this is why I am using this approach here now. However, for this little example with just 5 character searching in an array might probably be even faster than in a map.

Pre-processing

As soon as you know the word you can pre-process a map which maps each character in the word to its position in the word. As there might be many positions for the same character I store the positions in a list.

Checking guesses

Now when you have to check a guess you iterate over all characters of the guess and you can now use the pre-processed map to check whether a character is in the word (i.e in the map) or not. This will happen in constant time O(1) independent of the size of the word.

If the character is in the map, retrieve the associated list of positions for this character and iterate over this list in order to check if any of the positions match the position in the guess. If so, the letter is at the correct position, if not, it is in the word but at a wrong position.

Java program

Unfortunately I am not a C programmer but I believe the following Java code should easily be portable to C . Instead of Java's HashMap you may use std::unordered_map and the rest should just be some small differences in syntax. This is just a simple implementation of Wordle in Java without getting into too much detail but it should be sufficient as a reference for your implementation.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Simple implemantation of Wordle.
 */
public class Wordle {
    // word to guess
    private String word;
    // map: Character in word -> list of positions of that character in the word
    private HashMap<Character, List<Integer>> wordLookup;

    public Wordle(String word){
        this.word = word;
        // allocate memory for lookup table containing characters of word and their positions within the word
        this.wordLookup = new HashMap<>(word.length());
        var wordCharArr = word.toCharArray();
        // for each character in the word save it's position
        for (int i = 0; i < wordCharArr.length; i  ) {
            if(this.wordLookup.containsKey(wordCharArr[i])){
                // a character appears more than once -> add the other position to the list of positions
                var positionsList = this.wordLookup.get(wordCharArr[i]);
                positionsList.add(i);
            } else {
                var positionsList = new ArrayList<Integer>();
                positionsList.add(i);
                this.wordLookup.put(wordCharArr[i], positionsList);
            }
        }
    }

    public void checkGuess(String guess){
        checkGuess(guess.toCharArray());
    }

    public void checkGuess(char[] guess){
        System.out.println("Checking you guess...");
        for (int i = 0; i < guess.length; i  ) {
            var guessedChar = guess[i];
            // lookup if guessed character is in word
            if(wordLookup.containsKey(guessedChar)){
                // guessed character is in word
                // is it in (one of) the right position(s)?
                var posInWord = wordLookup.get(guessedChar);
                int finalI = i;
                if(posInWord.stream().anyMatch(pos -> finalI == pos)){
                    // character also is at the right position (this implementation does not signal that there may be multiple positions this character might go)
                    System.out.printf("> %c is correct at position %s!\n", guessedChar, i);
                }
                else {
                    // character is not at the right position
                    System.out.printf("> %c is in word but not at the right position!\n", guessedChar);
                }
            } else {
                // guessed character is not in word
                System.out.printf("> %c is not in word!\n", guessedChar);
            }
        }
        System.out.println("Done.");
    }

    public String getWord() {
        return word;
    }

    public void setWord(String word) {
        this.word = word;
    }

    public HashMap<Character, List<Integer>> getWordLookup() {
        return wordLookup;
    }

    public void setWordLookup(HashMap<Character, List<Integer>> wordLookup) {
        this.wordLookup = wordLookup;
    }

    public static void main(String[] args) {
        // create a game of Wordle for the word "hello"
        var aGameOfWordle = new Wordle("hello");
        // get user input for a guess here
        //...
        // check guesses..
        aGameOfWordle.checkGuess("hello");
        aGameOfWordle.checkGuess("holas");
    }
}

Expected output:

Checking you guess...
> h is correct at position 0!
> e is correct at position 1!
> l is correct at position 2!
> l is correct at position 3!
> o is correct at position 4!
Done.
Checking you guess...
> h is correct at position 0!
> o is in word but not at the right position!
> l is correct at position 2!
> a is not in word!
> s is not in word!
Done.
  •  Tags:  
  • c
  • Related