仿照手机上的拼音输入法

手机的汉字拼音输入法很'聪明',只要用数字键组合,就能够自动找到能组成拼音的字母组合。
从2代表abc,3:def,4:ghi,5:jkl,6:mno,7:pqrs,8:tuv,9:wxyz

写一个程序,对输入的数字组合,找到匹配的字母组合成拼音输出。
如果有多个匹配则按照字母顺序排列后输出。

pinyin2.txt文件,在这里下载

#pragma warning(disable:4786)

#include 
<cstdio>
#include 
<cassert>
#include 
<vector>
#include 
<algorithm>
#include 
<string>

using namespace std;

class NameList
{
public:
    
void init()
    
{
        
string a;
        
for (int j = 0; ym[j]; j++)
        
{
            a 
= ym[j];
            mStrs.push_back(a);
            
for (int i = 0; sm[i]; i++)
            
{
                a 
= sm[i];
                a 
+= ym[j] ;
                mStrs.push_back(a);
            }

        }

    }

    
void load(const char *file)
    
{
        
char buf[128];
        
char buf2[1024];
        
string a;
        mStrs.clear();
        mStrGBs.clear();
        FILE 
*fp = fopen(file,"rt");
        
while(fscanf(fp, "%s %s", buf, buf2) == 2)
        
{
            a 
= buf;
            mStrs.push_back(a);
            a 
= buf2;
            mStrGBs.push_back(a);
        }

        fclose(fp);
    }

    
void show()
    
{
        
for (vector< string >::iterator s = mStrs.begin(); s != mStrs.end(); ++s)
        
{
            printf(
"%s ", s->c_str());
        }

    }

    vector
< string > mStrs;
    vector
< string > mStrGBs;
private:
    
static const char *sm[];
    
static const char *ym[];
}
;

const char *NameList::sm[]=
{
    
"b","p","m","f","d""t","n","l","g","k",
    
"h","j","q","x","z""c","s","zh","ch","sh",
    
"r","y","w",
    NULL,
}
;
const char *NameList::ym[]=
{
    
"a","ai","ao","an","ang",
    
"o","ou","ong",
    
"e","ei","er","en","eng",
    
"i","iang","ian","iao","in","ing","iu","ia","ie","iong",
    
"u","uo","uang","un","uai","uan",
    
"ui","ue","ua",
    NULL,
}
;
class Digit2PinyinConverter
{
public:
    
struct StrCmpFunctor
    
{
        
operator () (const char *s1, const char *s2)
        
{
            
int len1 = strlen(s1);
            
int len2 = strlen(s2);
            
if (len1 != len2)
                
return len1 < len2;
            
return strcmp(s1, s2) < 0;
        }

    }
;
    
void init()
    
{
        validStrings.clear();
        vector
< string >::iterator name = namelist.mStrs.begin();
        
while(name != namelist.mStrs.end())
        
{
            validStrings.push_back(name
->c_str());
            
++name;
        }

        digits 
= "";
        sort(validStrings.begin(), validStrings.end(), StrCmpFunctor());
    }

    
/// @param char digit '2'..'9'
    void push(char digit)
    
{
        
if (digit < '2' || digit > '9')
            
return;
        digits 
+= digit;
        vector
< const char * > next;
        vector
< const char * >::iterator name = validStrings.begin();
        
while(name != validStrings.end())
        
{
            
if (match(*name, digits.size() - 1, digit))
            
{
                next.push_back(
*name);
            }

            
++name;
        }

        validStrings 
= next;
        sort(validStrings.begin(), validStrings.end(), StrCmpFunctor());
    }


    
void show()
    
{
        printf(
"+-------+-------+-------+\n");
        printf(
"|       |2 abc  |3 def  |\n");
        printf(
"+-------+-------+-------+\n");
        printf(
"|4 ghi  |5 jkl  |6 mno  |\n");
        printf(
"+-------+-------+-------+\n");
        printf(
"|7 pqrs |8 tuv  |9 wxyz |\n");
        printf(
"+-------+-------+-------+\n");
        printf(
"|-|0|+|\n");
        printf(
"+-------+-------+-------+\n");
    }

    
string digits;
    vector
< const char * > validStrings;
    
static NameList namelist;
private:  
    
bool match(const char *name, int pos, char digit)
    
{
        assert(digit 
>= '0' && digit <= '9');
        
int len = strlen(name);
        
if (len <= pos)
            
return false;
        
char d = name[pos];
        
const char *maplist = map[digit - '0'];
        
for (; *maplist; maplist++)
        
{
            
if (d == *maplist)
                
return true;
        }

        
return false;
    }

    
static const char *map[10];
}
;
const char *Digit2PinyinConverter::map[10]=
{
    
"""","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"
}
;
NameList Digit2PinyinConverter::namelist;

int main()
{
    
char c = '0';
    
int page = 0;
    
int i;

    Digit2PinyinConverter converter;
    Digit2PinyinConverter::namelist.load(
"pinyin2.txt");
    converter.init();
    
do
    
{
        
if (c == '\n')
            
continue;
        
if (c == '0')
            converter.init();
        
if (c == '+')
        
{
            page
++;
            
int maxpage = (converter.validStrings.size() + 9)/10;
            
if (page > maxpage)
                page 
= maxpage;
        }

        
if (c == '-' && page > 0)
            page
--;
        
if (c >= '2' && c <= '9')
        
{
            page 
= 0;
            converter.push(c);
        }

        
        system(
"cls");
        converter.show();
        
for (i = 0; i < (int)converter.digits.size(); i++)
            printf(
"%c", converter.digits[i]);
        printf(
"\n");
        
for (i=0;i<10 && i + page * 10 < (int)converter.validStrings.size();i++)
        
{
            
if (strlen(converter.validStrings[i + page * 10]) > strlen(converter.digits.c_str()))
                
break;
            printf(
"%d:%s ", i, converter.validStrings[i + page * 10]);
        }

        printf(
"\nPage %d, Total %d\n", page, converter.validStrings.size());
    }
 while(scanf("%c"&c) == 1);

    
return 0;
}

原文地址:https://www.cnblogs.com/kaikai/p/219569.html