一 判断两个字符串是否互为变形词
【题目】给定两个字符串str1和str2,如果str1和str2中出现的字符种类一样且每种字符出现的次数也一样,那么str1与str2互为变形词。请实现函数判断两个字符串是否互为变形词。
public boolean isDeformation(String str1, String str2)
{
// 判断输入字符串是否为空,以及长度是否相同
if (str1 == null || str2 == null || str1.length() != str2.length()) {
return false;
}
char[] chas1 = str1.toCharArray(); // 将字符串 str1 转换为字符数组
char[] chas2 = str2.toCharArray(); // 将字符串 str2 转换为字符数组
int[] map = new int[256]; // 创建一个长度为 256 的辅助数组 map,用于统计字符的出现次数
// 统计字符出现的次数
for (int i = 0; i < chas1.length; i++) {
map[chas1[i]]++; // 字符 chas1[i] 的 ASCII 值作为索引,自增对应位置的元素
}
// 遍历字符数组 chas2,判断字符的出现次数是否与 chas1 一致
for (int i = 0; i < chas2.length; i++) {
if (map[chas2[i]]-- == 0) { // 如果字符 chas2[i] 的出现次数为 0,则返回 false
return false;
}
}
return true; // 返回 true,表示 str1 和 str2 互为变形词
}
函数 isDeformation
的作用是判断两个字符串 str1
和 str2
是否互为变形词。
在方法中,首先判断输入字符串 str1
和 str2
是否为空,以及它们的长度是否相同。如果条件不满足,直接返回 false
。
然后,将字符串 str1
和 str2
分别转换为字符数组 chas1
和 chas2
。
接下来,创建一个长度为 256 的辅助数组 map
,用于统计字符的出现次数。
通过遍历 chas1
数组,将字符出现的次数统计到 map
数组中。
再遍历 chas2
数组,依次检查字符的出现次数,如果发现有字符的出现次数为 0,就返回 false
。
最后,如果没有发现出现次数不一致的情况,就返回 true
,表示 str1
和 str2
互为变形词。
二 判断两个字符串是否互为旋转词
【题目】如果一个字符串为str,把字符串str前面任意的部分挪到后面形成的字符串叫作str的旋转词。比如str="12345",str的旋转词有"12345"、"23451"、"34512"、"45123"和"51234"。给定两个字符串a和b,请判断a和b是否互为旋转词。
【举例】
【要求】如果a和b长度不一样,那么a和b必然不互为旋转词,可以直接返回false。当a和b长度一样,都为N时,要求解法的时间复杂度为O(N)。
判断两个字符串是否互为旋转词的方法如下:
1. 首先判断两个字符串的长度是否相等,如果不相等,直接返回false。
2. 将字符串a与自身拼接,形成新的字符串newStr。
3. 在newStr中查找是否包含字符串b,如果包含,则说明a和b是互为旋转词,返回true;否则,返回false。
以下是一个Java示例代码实现:
```java
public boolean isRotation(String a, String b) {
if (a.length() != b.length()) {
return false;
}
String newStr = a + a;
return newStr.contains(b);
}
```
使用KMP算法
public boolean isRotation(String a, String b) {
if (a == null || b == null || a.length() != b.length()) {
return false;
}
// 将b字符串重复一遍拼接成新的字符串b2
String b2 = b + b;
// 判断b2是否包含a,若包含则a和b互为旋转词,返回true;否则返回false
return b2.contains(a);
}
// 判断字符串s是否包含子串m
private boolean getIndexOf(String s, String m) {
if (s == null || m == null || m.length() < 1 || s.length() < m.length()) {
return false;
}
char[] ss = s.toCharArray();
char[] ms = m.toCharArray();
int si = 0; // 字符串s的索引
int mi = 0; // 子串m的索引
int[] next = getNextArray(ms); // 获取子串m的next数组
// 使用KMP算法进行匹配
while (si < ss.length && mi < ms.length) {
if (ss[si] == ms[mi]) {
si++;
mi++;
} else if (next[mi] != -1) {
// 当前字符不匹配且子串m的索引不为-1时,向前跳到next[mi]的位置
mi = next[mi];
} else {
// 当前字符不匹配且子串m的索引为-1时,字符串s的索引向前移动一位
si++;
}
}
// 如果子串m的索引达到末尾,说明匹配成功
if (mi == ms.length) {
return true;
} else {
return false;
}
}
// 获取子串m的next数组
private int[] getNextArray(char[] ms) {
if (ms.length == -1) {
return new int[] {-1};
}
int[] next = new int[ms.length];
next[0] = -1;
next[1] = 0;
int pos = 2; // 下一个计算next值的位置
int cn = 0; // 当前跳到的位置
while (pos < next.length) {
if (ms[pos - 1] == ms[cn]) {
// 当前字符与跳到的位置字符相等,next值为cn+1,pos和cn都后移
next[pos++] = ++cn;
} else if (cn > 0) {
// 当前字符与跳到的位置字符不相等,且cn>0,向前跳到next[cn]的位置
cn = next[cn];
} else {
// 当前字符与跳到的位置字符不相等,且cn=0,next值为0,pos后移
next[pos++] = 0;
}
}
return next;
}