Pig Latin(儿童黑话)
我是怎么接触到Pig Latin的?
实际上我是在C++ Program Algorithm(中译版)黑皮书上接触到的,当时看到这个短语还以为是跟猪相关,真是贻笑大方了。实际上这是个语言游戏,只不过也可以用来进行简单的语言加密。
后来在查阅资料的时候,发现了一个很有趣的一段话:”Ix-nay on the upid-stay.”。这段话出现在狮子王1中dodo鸟Zazu(沙祖)在大象墓地说的话,大概意思就是愚蠢的nalx。upid-stay实际上就是stupid,是一种非常地道的英语表达。
什么是Pig Latin?
儿童黑话(Pig Latin)是一种英语语言游戏,形式是在英语加上一点规则使发音改变。据说是由在德国的英国战俘发明来瞒混德军守卫的。儿童黑话于50年代和60年代在英国利物浦达到颠峰,各种年纪和职业的人都有使用。儿童黑话多半被儿童用来瞒著大人秘密沟通,有时则只是说著好玩。虽然是起源于英语的游戏,但是规则适用很多其他语言。
Pig Latin规则?
- 假设单词以辅音字母开始,将词首的辅音字母字符串(第一个元音字母前的全部字母)从单词的开头移动到末尾,然后加上后缀ay,这样就形成了它的pig latin。
- 比如说ball,它的第一个元音是a,那么它的Pig Latin就是all-bay.
- three,元音是e,变成ee-thray.
怎么样?是不是很容易理解?
- 那么对于元音字母开头的单词,该怎么描述它的黑话?仅仅加入后缀ay就可以,也可以是way,yay,hay。为了方便统一,在本文一律用way后缀。
- 让我们看看一个示例
One-way o-whay as-hay een-say e-thay ocean-way inks-thay othing-nay of-way ere-may ivers-ray.
(中译:曾经沧海难为水)
(英语:One who has seen the ocean thinks nothing of mere rivers.)
如何用代码实现Pig Latin语言加密?(以JAVA为例,实现单词Pig Latin加密,语句加密在本篇暂不实现,期待后续实现)
- 首先第一步,当然是要找出第一个元音字母的位置。(已知元音字母有a,e,i,o,u,其他的都是辅音字母)
- 第二步,判断元音字母出现的位置,如果是一个位置,则把备用后缀设为way,否则是ay
- 第三步,在第一个元音字母位置分离,把单词分离为两个部分。比如ball,分离为b和all.
- 第四步,将分离后的第二个部分放在首部,第一个部分放在尾部。
- 第五步,在第四部拼合的结果上,在尾部加入后缀。
那么整个编程的思路就很明了了,接下来开始撸代码。
全部代码我就放在结尾了,因为,你知道的,很影响阅读效率。
判断是否是元音字母
1 2 3 4 5 6 7 8 9 10 11 12
| private static boolean isVowel(char ch) { switch(ch) { case 'a': case 'e': case 'i': case 'o': case 'u': return true; default : return false; } }
|
这个代码也很简单就是swith-case判断,但是有一个致命问题,就是没有办法分辨大写字母情况,实际上行首的字母通常是大写的,而且大写的元音字母也是元音。so,我们应该加上所有的大写字母吗?加上所有的元音大写字母的话,整个方法会显得很臃肿。实际上java里面String类有一个方法equalsIgnoreCase判断字母是否为指定字符而忽略大小写。
修改后的判断是否是元音字母代码
1 2 3 4 5 6 7 8 9 10 11
| private static boolean isVowel(char ch) { String str = String.valueOf(ch); if(str.equalsIgnoreCase("a")| str.equalsIgnoreCase("e")| str.equalsIgnoreCase("i")| str.equalsIgnoreCase("o")| str.equalsIgnoreCase("u")) { return true; } return false; }
|
还有一个问题,在找到元音字母后如何进行字符串倒置,我的实现代码是这样的
1 2 3 4 5 6
| private static String reversalWord(String beforeWord,int index) { String frontWord = beforeWord.substring(0,index); String breakWord = beforeWord.substring(index); return breakWord.concat(frontWord); }
|
结果输出
One -> Oneway
剩下的都是没什么了,有兴趣的话可以看看结尾的全部代码
缺陷
- 还可以进一步优化思路,提高程序健壮程度,降低时间复杂度。
- 只是实现了单个单词的Pig Latin加密,句子的Pig Latin加密没有实现,因为句子的情况更为复杂。
全部代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| package exercise1;
import java.util.Scanner; import java.util.StringTokenizer;
public class test2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); String word=scanner.nextLine(); System.out.println(translateWord(word)); }
private static String translateWord(String inputWord) { String breakWord = ""; String afterWord = ""; StringBuilder endWord = new StringBuilder(); int i = indexOfVowel(inputWord);
if(i >= 0) { if(i == 0) { breakWord = "way"; endWord.append(inputWord); endWord.append(breakWord); }else { breakWord = "ay"; endWord.append(reversalWord(inputWord,i)); endWord.append(breakWord); } return endWord.toString();
}else { return inputWord; } }
private static String reversalWord(String beforeWord,int index) { String frontWord = beforeWord.substring(0,index); String breakWord = beforeWord.substring(index); return breakWord.concat(frontWord); }
private static int indexOfVowel(String inputWord) { for(int i = 0;i < inputWord.length();i++) { if(isVowel(inputWord.charAt(i))) { return i; } } return -1; }
private static boolean isVowel(char ch) { String str = String.valueOf(ch); if(str.equalsIgnoreCase("a")| str.equalsIgnoreCase("e")| str.equalsIgnoreCase("i")| str.equalsIgnoreCase("o")| str.equalsIgnoreCase("u")) { return true; } return false; }
}
|
参考资料:
char转化为String
儿童黑话介绍
相关代码参考