具有相同索引的数组已更改而未重新分配

Posted

技术标签:

【中文标题】具有相同索引的数组已更改而未重新分配【英文标题】:array with same index changed without being reassigned 【发布时间】:2012-07-03 01:28:03 【问题描述】:

我在使用这个程序时遇到了问题。它的目的是读取一个单词列表,然后输入这个单词有多长,从这个长度的单词中,计算其中所有字母的总数,按最高频率排序,然后询问使用频率最高的用户。在它询问之前,它会检查该字母是否已被询问是否在数组 prevguess 中循环。我的问题是,如果我输入“yesletter”为真,则该数组的内容会在内联注释“此处发生问题”之后的位置发生更改。我输入的这个测试循环中 q 的值没有改变,但值本身会改变。

我知道main中的循环现在是无限的,但是程序还没有结束。

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int i(0),n(0),counter(0),limit(0),length,mastercount(0);
int acount(0),bcount(0),ccount(0),dcount(0),ecount(0),fcount(0),gcount(0),hcount(0);
int icount(0),jcount(0),kcount(0),lcount(0),mcount(0),ncount(0),ocount(0),pcount(0);
int qcount(0),rcount(0),scount(0),tcount(0),ucount(0),vcount(0),wcount(0),xcount(0),ycount(0),zcount(0);
int letters[2][26];
char prevguess[26];
char words[60000][30];


void initarray() 

    int len(0);
    string line;
    char temp;

    ifstream wordlist ("words.txt");

    if (wordlist.is_open())
    
        while (wordlist.good())
        
            getline (wordlist,line);
            len=line.length();

            for (n=0;n<30;n++)
            
                if (n<len)
                    temp=line.at(n);
                    words[i][n]=temp;
                
                else
                    words[i][n]='*';
                
            

            i++;
            counter++;
        
    
    else
    
        cout<<"file not opened";
    
    wordlist.close();


void selectlength()

    int x(0),y(0);
    bool shorter(false),longer(false);

    cout <<"length of word"<<endl;
    cin >> length;

    limit=counter;
    counter=0;

    for (i=0;i<limit;i++)

        shorter=false;
        longer=false;

        for (n=0;n<length;n++)
            if (words[i][n]=='*')
            
                shorter=true;
                break;
            
        

        if (words[i][length] != '*')
        
            longer=true;
        

        if (!longer && !shorter)
        
                n=0;
                for (y=0;y<30;y++)
                
                    if (n<length)
                        words[x][y]=words[i][n];
                        n++;
                    
                    else
                        words[x][y]='*';
                    
                
                x++;
                counter++;

        

    


void mostletters()
    char temp;

    for (i=0;i<counter;i++)
        for (n=0;n<=length;n++)

            temp=words[i][n];
            switch (temp)
                case 'a':
                    acount++;
                    break;
                case 'b':
                    bcount++;
                    break;
                case 'c':
                    ccount++;
                    break;
                case 'd':
                    dcount++;
                    break;
                case 'e':
                    ecount++;
                    break;
                case 'f':
                    fcount++;
                    break;
                case 'g':
                    gcount++;
                    break;
                case 'h':
                    hcount++;
                    break;
                case 'i':
                    icount++;
                    break;
                case 'j':
                    jcount++;
                    break;
                case 'k':
                    kcount++;
                    break;
                case 'l':
                    lcount++;
                    break;
                case 'm':
                    mcount++;
                    break;
                case 'n':
                    ncount++;
                    break;
                case 'o':
                    ocount++;
                    break;
                case 'p':
                    pcount++;
                    break;
                case 'q':
                    qcount++;
                    break;
                case 'r':
                    rcount++;
                    break;
                case 's':
                    scount++;
                    break;
                case 't':
                    tcount++;
                    break;
                case 'u':
                    ucount++;
                    break;
                case 'v':
                    vcount++;
                    break;
                case 'w':
                    wcount++;
                    break;
                case 'x':
                    xcount++;
                    break;
                case 'y':
                    ycount++;
                    break;
                case 'z':
                    zcount++;
                    break;

            
        
    


void guessmost()
    int x,y,temp,temp2,q;

    for (x=0;x<26;x++)

        letters[0][x]=x;

        switch (x)
            case 0:
                letters[1][x]=acount;
                break;
        case 1:
            letters[1][x]=bcount;
            break;
        case 2:
            letters[1][x]=ccount;
            break;
        case 3:
            letters[1][x]=dcount;
            break;
        case 4:
            letters[1][x]=ecount;
            break;
        case 5:
            letters[1][x]=fcount;
            break;
        case 6:
            letters[1][x]=gcount;
            break;
        case 7:
            letters[1][x]=hcount;
            break;
        case 8:
            letters[1][x]=icount;
            break;
        case 9:
            letters[1][x]=jcount;
            break;
        case 10:
            letters[1][x]=kcount;
            break;
        case 11:
            letters[1][x]=lcount;
            break;
        case 12:
            letters[1][x]=mcount;
            break;
        case 13:
            letters[1][x]=ncount;
            break;
        case 14:
            letters[1][x]=ocount;
            break;
        case 15:
            letters[1][x]=pcount;
            break;
        case 16:
            letters[1][x]=qcount;
            break;
        case 17:
            letters[1][x]=rcount;
            break;
        case 18:
            letters[1][x]=scount;
            break;
        case 19:
            letters[1][x]=tcount;
            break;
        case 20:
            letters[1][x]=ucount;
            break;
        case 21:
            letters[1][x]=vcount;
            break;
        case 22:
            letters[1][x]=wcount;
            break;
        case 23:
            letters[1][x]=xcount;
            break;
        case 24:
            letters[1][x]=ycount;
            break;
        case 25:
            letters[1][x]=zcount;
            break;
        
    


    for (y=0;y<26;y++)



        //problem occurs here (I think)

        for (q=mastercount-1;q>=0;q--)
                    cout<<"for array index:"<<q;
                    cout << " the value of prevguess is "<<prevguess[q]<<endl;
        





        for (x=26;x>=1;x--)
            if (letters[1][x]>letters[1][x-1])
            
                temp=letters[1][x-1];
                letters[1][x-1]=letters[1][x];
                letters[1][x]=temp;

                temp2=letters[0][x-1];
                letters[0][x-1]=letters[0][x];
                letters[0][x]=temp2;
            
        

    


void letterguess()
    int x(0),z;
    char guess;
    bool goodletter(false),yesletter(false),alreadyguess(false);

    while (!goodletter)

        guess=letters[0][x]+97;

        if (mastercount==0)
            alreadyguess=false;
        
        else
            for (z=mastercount-1;z>=0;z--)
                if (guess==prevguess[z])
                    alreadyguess=true;
                
            
        

        if (!alreadyguess)
            cout<<"is your letter "<< guess<<endl;
            cin >> yesletter;
            prevguess[mastercount]=guess;
        

        if (yesletter && !alreadyguess)
            goodletter=true;
        
        else 
            cout<<"wrong"<<endl;
            x++;
        

        mastercount++;

        if (mastercount>26)
                    break;
                
    



int main() 
    bool found(false);
    initarray();
    selectlength();
    while (!found)
        mostletters();
        guessmost();
        letterguess();
        if (mastercount>26)
            break;
        

    

【问题讨论】:

每个字母 (char) 都有一个唯一的 ascii 值,最好将字母转换为包含 ascii 值的 int 并使用数组来引用每个字母计数,而不是定义大量变量和一个巨大的 switch 语句。我还会考虑使用#ifdef DEBUG 和/或断言语句将一些调试代码放入您的程序中。有人可能会给你答案,但你最好使用工具。 以上内容:声明 int letter[26];将 mostletters() 开关替换为: int temp = (int) words[i][n]-97; if(temp>=0 and temp 你真的应该缩小问题的范围。我什至不确定你是在问问题。 @user1489736 好主意!这减少了很多不必要的代码,而且效果很好。谢谢。 【参考方案1】:

我相信问题开始时比您的评论要低一些。

for (x=26;x>=1;x--)
       if (letters[1][x]>letters[1][x-1])

x 为26 时,letters[1][x] 将超出范围。

【讨论】:

哇,这是对的,谢谢。但如果你能帮助我理解为什么它首先被破坏,那就太好了。您提到的代码上方的数组返回不同的值,即使 q 的起始值始终相同,并且在这些循环完成之前不会访问它输出的数组。这是为什么?再次感谢! 当您尝试访问数组中的更多元素时,您会得到随机值(充其量)。如果你在数组之外写,那可能会影响其他变量并使一切变得混乱。我们不知道以后会发生什么

以上是关于具有相同索引的数组已更改而未重新分配的主要内容,如果未能解决你的问题,请参考以下文章

架构更改是不是需要重新索引所有 Solr 文档或仅包含已更改架构字段的文档?

滚动旋转时 UICollectionView 崩溃(索引路径处补充项目的布局属性已更改而未失效..)

更改特定索引而不在 Vuejs 中重新渲染整个数组

为什么将一个对象的值分配给另一个对象的值,然后重新分配原始对象会更改两个对象?

在不更改索引的情况下重新排序数组

如何在 Matlab 中将字符数组的偶数和奇数索引重新分配到一个新的较小字符数组中?