【问题标题】:How to get a program to compare two arrays then see if the two arrays have the same characters如何让程序比较两个数组然后查看两个数组是否具有相同的字符
【发布时间】:2018-04-07 04:13:06
【问题描述】:

这是家庭作业 所以我必须编写一个简单的拼字游戏。我在整个程序中都有 cmets,但我会在这篇文章的结尾解释我想要做什么。

 #include <stdio.h> 
 #include <stdbool.h> 
 #include <stdlib.h> 
 #include <time.h> 
#define N 96

 int main() {
srand((unsigned) time(NULL));
int letter_set = N , size_let = 7 , num_let = 7 , max_size_word = 7 , size_letter_set = 7, size_word, arr[N];
char word [7]; 
printf("This program plays a game of scrabble.\n");

generate_letter_set(letter_set , size_let , num_let, arr);
read_word(word, max_size_word);
check_word(word, size_word, letter_set, size_letter_set, arr);

return 0;
}


 void generate_letter_set(int letter_set[] , int size_let , int num_let, int arr[])  
{


const char let[26] = 
{'K','J','X','Q','Z','B','C','M','P','F','H','V','W','Y','G','L','S','U','D','N','R','T','O','A','I','E'};

int freq[26] = 
{ 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 6, 6, 6, 8, 9, 9, 12 };

const int score[26] =
{ 5, 8, 8, 10, 10, 3, 3, 3, 3, 4, 4, 4, 4, 4, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1};

    int index = 0; 
        for(int i = 0 ; i < 26 ; i++) {
            for(int f = 0 ; f < freq[i]; f++) {
                arr[index++] = let[i];  //All the 96 letters are stored in let[i]
            //printf("%c " , let[i]);  // Created the letter bank for all the letters 

        } 
    }       

    int letter;
        printf("Your letters are: ");
            for(int l = 0; l < 7; l++){
                letter = rand() % 97;   //Gives the user their letters all the letters are from arr[letter] 
            printf("%c ", arr[letter]);


        }   

 }
   int read_word(char word[], int max_size_word) {

{
          int c = 0, let_count = 0;
            printf("\nPlease enter your word: ");
        char input = toupper(getchar());
                for(c = 0; c < max_size_word; c++) {

    if(input != '\n')
{       word[c] = input;   
            let_count++;
    }
    else if(input == '\n')
    input = toupper(getchar());     //The word the user entered is in word[c]
                                    }

return let_count;
 }

    }
 int check_word(char word[], int size_word, int letter_set[], int 
  size_letter_set, int arr[]) {
//Figure out how to pass two arrays through the functions
//Pass word[c] into this function 
//Pass arr[letter] into this function then compare the two arrays
//Make it so the user has to enter less than 7 chars
for (int a; a < 7; a++) {

    if (word[a] != arr[a]) {
printf("Use your letters");
 }

}


 return 1;
} 

所以我在这个程序中唯一的问题是我将如何让我的“check_word”函数工作。此功能必须检查用户是否输入了提供的字母。在拼字游戏中,你得到 7 个字母,给用户的 7 个字母的数组存储在 (arr[]) 然后'read_word'函数中的字母是用户进入。输入的字母存储在 word[] 中。所以我检查用户是否真的使用了 arr[] 中的字母的直觉是做一个比较两个数组 arr[]word[ ]。但是我意识到这将检查用户是否真的使用了每一个字母,我只需要检查用户是否使用了任何未提供的字母。我不知道如何做到这一点,任何帮助将不胜感激!如果需要任何澄清,也请在 cmets 中告诉我,我也为这个巨大的帖子道歉。

【问题讨论】:

  • 您不是已经在这里发布了这个问题吗:stackoverflow.com/questions/46901918/… 您可以编辑您的帖子以进一步澄清而不是重新发布。就像我在那里发布的那样,为用户提供的字母建立一个频率表,并将它们与建议单词中的字母进行核对。
  • @MFisherKDX ,对不起,我对这个网站有点陌生,我没有意识到有一个编辑选项,但是频率表不会在拼字游戏中包含每个可能的字母吗?
  • letter = rand() % 97; 是在'A''Z' 范围内选择一个字母的糟糕方法。另外,字母袋应该有每个字母瓦片的特定数量,所以我建议你找到一种算法,随机挑选一个瓦片并将其从袋子中取出。磁贴必须是带有字符和分数的struct。根据剩余的数量从袋子(一个数组)中选择一个瓦片struct,并调整数组。
  • @Weather Vane 我明白你在说什么,但对于这个项目来说,这不是必需的,因为用户只会玩一次拼字游戏,所以从数组中递减字母不会产生任何影响。跨度>
  • 我可以看到您尝试使用int freq[26] 对可用的瓷砖数量进行建模,但仍然可以在信包中使用struct 数组。

标签: c arrays boolean


【解决方案1】:

所以我在这个程序中唯一的问题是如何让我的“check_word”函数工作。这个函数必须检查用户是否输入了提供的字母。在拼字游戏中,你得到 7 个字母,给用户的 7 个字母的数组存储在 (arr[]) 中,然后在 'read_word' 函数中是用户输入的字母。

有很多方法可以解决这个问题。这是一种方法。建立提供给用户的字母的频率表。因此,如果已向用户提供:R S T L N E E,则 freq['R'] = 1freq['S] = 1freq['T'] = 1freq['L'] = 1freq['N'] = 1freq['E'] = 2freq 中的所有其他值都是 0。然后当用户输入一个单词时,您可以遍历每个字母并从该字母的频率表中减去 1。如果任何值小于 0,则该词无效。

但是,您的代码中还有另一个关于随机化输入的问题——即:将字母处理给用户。 @Weathervane 在那里制作了一些可能有帮助的 cmets。考虑将所有字母放入set(或更准确地说是bag——因为字母可以重复)并从袋子中随机抽取一封信。重复 7 次(或直到袋子为空)。

【讨论】:

  • 好的,我理解这种方法是有道理的,但是编程明智的你会用循环遍历给定字母的数组。那么每个字母的频率如何设置为1呢?
  • 是的。将频率表初始化为全 0。用循环遍历每个给定的字母。如果字母是“A”,则增加freq['A']。现在是 1。
  • 为澄清起见,您所说的频率表与我在第一个函数中使用的频率表不同?
  • 是的。它不同,但相似。我看到了这一点,意识到了混乱。您的freq 数组指定了整个使用和未使用的字母的频率。我所指的表格仅指定了当前可供用户播放的字母的频率。如果这太令人困惑并且您更了解@xing 的方法,请使用他的方法。
  • 我明白你的方法了。我唯一感到困惑的部分是我将如何遍历给定字母数组中的每个字符并将每个字母的频率设置为 1。然后我将使用条件语句来检查用户输入的任何字母是否是通过递减频率表小于 1?
【解决方案2】:

由于从所有字母和您的字母中选择字母,它们被交换到数组的末尾,并且可用字母的数量减少。

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#define N 98

void generate_letter_set( char arr[], int *all, char yourletters[], int limit);
void read_word(char word[], int max_size_word);
int check_word(char word[], char yourletters[]);

int main ( void) {
    srand((unsigned) time(NULL));
    char arr[N] = "";
    char yourletters [8] = "";
    char word [8]= "";
    int pool = N;//available letters
    int size_let = 7;
    int num_let = 7;
    int max_size_word = 7;
    int size_letter_set = 7;
    int size_word;
    printf("This program plays a game of scrabble.\n");

    printf ( "pool of available letters is %d\n", pool);
    generate_letter_set( arr, &pool, yourletters, max_size_word);
    printf ( "\npool of available letters is now %d\n", pool);
    printf ( "\nyour letters %s\n", yourletters);
    read_word(word, max_size_word);
    if ( ( check_word(word, yourletters))) {
        printf ( "word %s is usable from your letters %s\n", word, yourletters);
    }
    else {
        printf ( "word %s is not usable from your letters %s\n", word, yourletters);
    }

    return 0;
}

void generate_letter_set(char arr[], int *all,char yourletters[], int limit)
{
    const char let[26] = {"KJXQZBCMPFHVWYGLSUDNRTOAIE"};

    int freq[26] =
    { 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 6, 6, 6, 8, 9, 9, 12 };

    const int score[26] =
    { 5, 8, 8, 10, 10, 3, 3, 3, 3, 4, 4, 4, 4, 4, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1};

    int index = 0;
    for(int i = 0 ; i < 26 ; i++) {
        for(int f = 0 ; f < freq[i]; f++) {
            arr[index++] = let[i];  //All the 98 letters are stored in let[i]
        }
    }

    int letter;
    char swap;
    printf("Your letters are: ");
    for(int l = 0; l < limit; l++){
        letter = rand() % *all;   //Gives the user their letters all the letters are from arr[letter]
        printf("%c ", arr[letter]);
        yourletters[l] = arr[letter];
        *all = *all - 1;//deduct from the number of available letters
        swap = arr[letter];//swap letter to end of array
        arr[letter] = arr[*all];
        arr[*all] = swap;
    }

}

void read_word(char word[], int max_size_word) {
    int c = 0;
    printf("\nPlease enter your word: ");
    for(c = 0; c < max_size_word; c++) {
        int input = toupper(getchar());

        if(input != '\n')
        {
            word[c] = input;
        }
        else if(input == '\n')
            break;     //The word the user entered is in word[c]
   }

    return;
}

int check_word(char word[], char valid[]) {
    char *check = word;//check is first letter in word
    char swap = ' ';
    int match = 0;
    int len = strlen ( valid);
    //Figure out how to pass two arrays through the functions
    //Pass word[c] into this function
    //Pass arr[letter] into this function then compare the two arrays
    //Make it so the user has to enter less than 7 chars

    while ( *check) {//loop until check points to '\0'
        for ( int each = 0; each < len; each++) {
            match = 0;
            //this printf is just for show and can be removed
            printf ( "check %c in %.*s\n", *check, len, valid);
            if ( *check == valid[each]) {
                match = 1;
                swap = valid[each];//swap letter to end of array
                valid[each] = valid[len - 1];
                valid[len - 1] = swap;
                len--;//deduct from avaiable letters
                break;
            }
        }
        if ( !match) {
            return 0;
        }
        check++;//next letter to check
    }

    return 1;
}

【讨论】:

    【解决方案3】:

    我对你的任务进行了编码,如果你有兴趣,我可以在代码中添加 cmets。

    它是如何工作的:

    1. 一开始创建的一袋瓷砖。瓦片存储在数组中,其中索引是 ascii 字母代码。 A 是 65,B 是 66,Z 是 90。所以,我们需要 90 个元素的数组,其中只使用从 66 到 90 的索引,其他不需要。所以,我做了下一个技巧 - 从字母的 ascii 代码中减去 65 并得到以下索引:A - 0、B - 1、Z - 26。现在,数组只需要 26 个元素。这种方法的优点是以 O(1) 的效率检测字母可用性。数组是否包含M 字母? - 检查array[12],如果它不为零,则包含该字母,否则不包含。两个for 循环是不必要的。
    2. 从袋子中创建和填充机架。也是array[26],但是里面只有7个tile,其他的都是0。
    3. 打印样品架内容并等待用户输入。用户应该用架子上的字母写一个单词。
    4. 检查,这个单词是否有效 - 遍历单词字母并检查,这个字母是否包含在机架中。如果是 - 从机架中删除该字母并处理该单词的下一个字母。例如,用户输入了单词catAscii 代码为 67,65,84(大写)。每个代码减去 65,我们得到2,0,19。机架阵列中是否存在此项目(非零)?是的 - 这个词是有效的。否 - 无效,“再试一次”。如果架子上的瓷砖少于 7 个,则从袋子中重新装满。
    5. 只要袋子或架子上还有牌,游戏就会继续。

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <time.h>
    #include <ctype.h>
    #define CNT 26
    //////////////////
    typedef struct tile {
        char letter;
        int amount;
        int points;
    } tile;
    /////////////
    typedef struct tiles_set {
        int tiles_num;
        int storage_size;
        tile storage[CNT];
    } tiles_set;
    
    void check_user_word(char *word, tiles_set rack_copy, tiles_set *rack_ptr); 
    void fill_rack(tiles_set *rack, int to_size); 
    void print_set(tiles_set set); 
    void bag_init(); 
    
    tiles_set bag;
    
    int main() {
        int rack_size = 7;
        char *user_word;
    
        srand((unsigned) time(NULL));
    
        bag_init();
    
        tiles_set rack;
        rack.storage_size = CNT;
        rack.tiles_num = 0;
        memset(rack.storage, 0, sizeof(rack.storage));
    
        while(bag.tiles_num > 0 || rack.tiles_num > 0) {
            fill_rack(&rack, rack_size);
    
            puts("Rack:");
            print_set(rack);
            printf("\nWrite your word: \n");
    
            fgets(user_word, rack_size + 2, stdin);
            check_user_word(user_word, rack, &rack);
        }
        return 0;
    }
    
    void check_user_word(char *word, tiles_set rack_copy, tiles_set *rack_ptr) {
        int i, ch, len;
    
        if(!strchr(word, '\n')) {
            printf("The word should be less or equal to the amount of tiles in the rack - %d tiles\n", rack_ptr->tiles_num);
            while(((ch = getchar()) != EOF) && (ch != '\n'));
            puts("Try again.");
            return;
        }
    
        len = strlen(word) - 1;
    
        char letter;
        for(i = 0; i < len; i++) {
            letter = toupper(word[i]) - 65;
    
            if(rack_copy.storage[letter].amount) {
                rack_copy.storage[letter].amount--;
                rack_copy.tiles_num--;
            } else {
                puts("You should use letters only from the rack. Try again.");
                return;
            }
        }
        *rack_ptr = rack_copy;
    }
    
    void fill_rack(tiles_set *rack, int to_size) {
        int i;  
        char letter;
        int cnt = to_size - rack->tiles_num;
        for(i = 0; i < cnt; i++) {
            if(bag.tiles_num <= 0) {
                puts("Tiles in the bag ended.");
                return;
            }
    
            do {
                letter = rand() / (RAND_MAX / bag.storage_size + 1);
            } while(!bag.storage[letter].amount);
    
            rack->storage[letter].letter = bag.storage[letter].letter;
            rack->storage[letter].amount++;
            rack->storage[letter].points = bag.storage[letter].points;
            rack->tiles_num++;  
    
            bag.storage[letter].amount--;
            bag.tiles_num--;
        }
    }
    
    void bag_init() {
        const char letters[CNT] = 
        {'K','J','X','Q','Z','B','C','M','P','F','H','V','W','Y','G','L','S','U','D','N','R','T','O','A','I','E'};
        int freq[CNT] = 
        { 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 6, 6, 6, 8, 9, 9, 12 };
        const int points[CNT] =
        { 5, 8, 8, 10, 10, 3, 3, 3, 3, 4, 4, 4, 4, 4, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1};
    
        bag.storage_size = CNT;
        bag.tiles_num = 98;
    
        int i;
        int letter_index;
        for(i = 0; i < bag.storage_size; i++) {
            letter_index = letters[i] - 65;
            bag.storage[letter_index].letter = letters[i];
            bag.storage[letter_index].amount= freq[i];
            bag.storage[letter_index].points = points[i];
        }
    }
    
    void print_set(tiles_set set) {
        int i, cnt;
        for(i = 0; i < set.storage_size; i++) {
            cnt = set.storage[i].amount;
            while(cnt > 0) {
                printf("%c ", set.storage[i].letter);
                cnt--;
            }
        }
        puts("");
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-11
      相关资源
      最近更新 更多