变位词(编程珠玑)

问题

给定一本英语单词词典,请找出所有的变位词集。所谓的变位词是指,组成各个单词的字母完全相同,只是字母排列的顺序不同。
例如,“pots”,”stop”和“tops”互为变位词,因为每个单词都可以通过改变其他单词中字母的顺序来得到。

解决思路

编程珠玑的变位词程序要按照三个步骤来执行,其中前一个步骤程序的输出作为下一个步骤程序的输入:

  • 程序标识单词。
  • 程序排序标识后的文件。
  • 程序将这些单词压缩为每个变位词类一行的形式。

单词的字典的处理过程:

由以上可看出需要三个程序的处理。

sign程序

假设输入单词的长度不超过100,对每个输入的单词依照字母进行排序,将结果输入这个单词所对应的“签名”。

sort程序

程序排序后的输出的“签名”,对其输出的结果排序,如上图。

squash程序

将同一个变位词类中的各个单词放到同一行中。

程序代码

C++代码

完整例子:先按照字符排序,比较是否是同一个字符串,输出字符串

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
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
//最简洁的换位词
void main()
{
char s1[1000]="stop",s2[1000]="opst";
int len1,len2;
//字符的长度
len1=strlen(s1);
len2=strlen(s2);
cout<<"排序前"<<endl;
cout<<"s1---------------------------"<<endl;
for(int i=0;i<len1;i++){
cout<<s1[i];
}
cout<<"-----------------------------"<<endl;
cout<<"s2---------------------------"<<endl;
for(int i=0;i<len2;i++){
cout<<s2[i];
}
cout<<"-----------------------------"<<endl;
//对给定区间所有元素进行排序
//有一个数组int a[100],要对从a[0]到a[99]的元素进行排序,只要写sort(a,a+100)就行了,默认的排序方式是升序
//按ASCII值大小排序
sort(s1,s1+len1);
sort(s2,s2+len2);
cout<<"排序后"<<endl;
cout<<"s1---------------------------"<<endl;
for(int i=0;i<len1;i++){
cout<<s1[i];
}
cout<<"-----------------------------"<<endl;
cout<<"s2---------------------------"<<endl;
for(int i=0;i<len2;i++){
cout<<s2[i];
}
cout<<"-----------------------------"<<endl;
//两个字符串自左向右逐个字符相比(按ASCII值大小相比较)
if(strcmp(s1,s2)==0){
cout<<"Yes"<<endl;
}else{
cout<<"No"<<endl;
}
}

字符排序:

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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std;


#define WORDMAX 100

//由小到大排序
int charcomp(const void *x , const void *y)
{
return *(char *)x - *(char *)y;
}

int main()
{
char word[WORDMAX], sig[WORDMAX];
while (scanf("%s", word) != EOF)
{
strcpy(sig, word);
//1 待排序数组首地址
//2 数组中待排序元素数量
//3 各元素的占用空间大小
//4 指向函数的指针,用于确定排序的顺序(排序规则)
//qsort(sig, strlen(sig), sizeof(char), charcomp);
//另一种排序
sort(sig,sig+strlen(sig));
printf("%s %s\n", sig, word);
}
return 0;
}

Java代码

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package 换位词;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class WordManipulation {

private Map<String, List<String>> result;
private String[] wordInput;

public WordManipulation(String[] word) {
this.wordInput = word;
}

/**
* string sort to find a lable like (mississippi,i4m1p2s4) 字符按照每个字母标识数量
*
* @param word
* The string to be sorted
* @return the string sorted
*/
private String sort(String word) {
// 按照字符(ASCII排序)
// <字符,相同字符数目>
Map<Character, Integer> map = new TreeMap<Character, Integer>();
for (int i = 0; i < word.length(); i++) {
char temp = word.charAt(i);
if (map.get(temp) == null) {
map.put(temp, 1);
} else {
int value = map.get(temp);
map.put(temp, ++value);
}
}
return map.toString();
}

/**
* squash the same label into a ArrayList 计算字符串是否是同一个,然后添加到同一个list中
*
* @param map
*/
private void squash(Map<String, String> map) {
result = new TreeMap<String, List<String>>();
Set<Map.Entry<String, String>> entrySet = map.entrySet();
for (Map.Entry<String, String> entry : entrySet) {
// 单词名字
String strKey = entry.getKey();
// 经过sort排序过后的字符相同数字
String strValue = entry.getValue();
System.out.println(strKey + " ----> " + strValue);
List<String> resultList;
if (result.get(strValue) == null) {
resultList = new ArrayList<String>();
} else {
resultList = result.get(strValue);
}
resultList.add(strKey);
result.put(strValue, resultList);
}
}

/**
* calculate the anagram
*/
public void doCalculate() {
Map<String, String> temp = new TreeMap<String, String>();
for (int i = 0; i < this.wordInput.length; i++) {
temp.put(this.wordInput[i], sort(this.wordInput[i]));
}
squash(temp);
print();
}

private void print() {
System.out.println(result.values());
}

public static void main(String[] args) {
String[] a = { "stop", "pots", "snap", "naps" };
WordManipulation wm = new WordManipulation(a);
wm.doCalculate();
}
}

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×