Java 替换字符及其所有匹配项后,计算匹配字符串的数目
我有一个字符串数组Java 替换字符及其所有匹配项后,计算匹配字符串的数目,java,string,algorithm,Java,String,Algorithm,我有一个字符串数组arr和另一个输入字符串s 现在我的任务是从s中选择一个字符,并用另一个字符替换s中出现的所有字母。然后根据需要重新排列字符,但这是可选的。现在计算其中有多少与数组元素匹配 我已经用Java编写了这方面的代码,但是我所采用的方法是不正确的 示例: s=aabbcdbb arr = {"aabbcdbbb", "aabbcdb", "aabbxdbb", "aabbbdbb", "aaccc
arr
和另一个输入字符串s
现在我的任务是从s
中选择一个字符,并用另一个字符替换s
中出现的所有字母。然后根据需要重新排列字符,但这是可选的。现在计算其中有多少与数组元素匹配
我已经用Java编写了这方面的代码,但是我所采用的方法是不正确的
示例:
s=aabbcdbb
arr = {"aabbcdbbb", "aabbcdb", "aabbxdbb", "aabbbdbb", "aacccdcc", "ddbbcdbb", "eebbcdbb"}
输出:
5
说明:
length of s = 8
sorting s = aabbbbcd
arr[0] = has 9 characters i.e more than s length so ignored
arr[1] = has 7 characters i.e less than s length so ignored
arr[2] = sorting : aabbbbdx. replace x with c and rearranging it makes this as aabbbbcd
arr[3] = sorting : aabbbbbd. replace 1 occurrence of b with c and rearranging it makes this as aabbbbcd
arr[4] = sorting : aacccccd. replace 4 occurrences of c with b and rearranging it makes this as aabbbbcd
arr[5] = sorting : bbbbcddd. replace 2 occurrences of d with a and rearranging it makes this as aabbbbcd
arr[6] = sorting : bbbbcdee. replace e with a and rearranging it makes this as aabbbbcd
so arr[2], arr[3], arr[4], arr[5], arr[6] matches the given requirement so output is 5.
我尝试了此程序,但某些输入失败:
static int process(String s, String[] arr) {
int matches = 0;
Map<Character, Integer> m = new HashMap<>();
// sort s
char[] c = s.toCharArray();
Arrays.sort(c);
s = new String(c);
c = s.toCharArray();
// get each char of s and count its occurrences
for(char k : c) {
m.put(k, m.getOrDefault(k, 0)+1);
}
for(String s1 : arr) {
// get array element
char[] c1 = s1.toCharArray();
// check if array element length matches with input string length
if(c1.length == c.length) {
// count each occurrence of char into array of alphabets
int[] chars = new int[26];
for(char k1: c1) {
chars[k1-'a']++;
}
// decrement count by checking with map
for(char k : m.keySet()) {
chars[k-'a'] -= m.get(k);
}
boolean f1 = false;
boolean valid = true;
int mismatch = 0;
int notzeros = 0;
// get each element from array of chars
for(int i=0; i<26; i++) {
int ch = chars[i];
// value not zero
if(ch != 0) {
// count number of non zeros
notzeros++;
// f1 is true, means its second occurrence of non zero element
if(f1) {
if(ch > 0) {
// check if values do not match
if(mismatch*-1 != ch) {
valid = false;
break;
}
} else {
// check if values do not match
if(mismatch != ch*-1) {
valid = false;
break;
}
}
}
// get the mismatch count and set the value of flag to true
f1 = true;
mismatch = ch;
}
// if non zero elements more than 2 then we can ignore this array element
if(notzeros > 2) {
valid = false;
break;
}
}
// check for possible solution.
if(valid && f1) {
matches++;
}
}
}
return matches;
}
我解决这项任务的方法不正确,正确的方法是什么?首先,您提供的解释似乎是基于对问题的一个稍微误解的表述。问题在于检查是否可以用字符串s中的不同字符而不是数组中的字符串替换出现的所有字符。 因此,例如,使用
s=“aabbcdbb”
和数组字符串“aabbbdbb”
,您可以将s
中的c
字符替换为b
,以获得数组字符串。不是相反的。这解释了两个输入样本的预期输出的不一致性(如注释中所述)
您的实现通常是正确的,但在特殊情况下失败。解决这个问题的方法基本上是生成一个“diff”数组,其中包含每个字符出现的差异。然后,您希望在diff中,只有两个不同的事件相互抵消。要使用上一个示例进行说明,请映射s
的字符:
a -> 2
b -> 4
c -> 1
d -> 1
与当前数组元素类似:
a -> 2
b -> 5
d -> 1
区别在于:
b -> 1
c -> -1
如果您有s=“aabb”
和字符串“abbb”
,则此操作失败,其中差异为:
a -> -1
b -> 1
这里的问题是,字符a
和b
都出现在字符串“abbb”
中。这将使匹配检查失败。原因是:如果我们想从“abbb”
转到“aabb”
,我们需要用a
替换b
。但是“abbb”
已经有一个a
字符,如果对方用b
替换a
,该字符就不存在了
可以修改代码以处理这种情况(使用diffInS1
的部件):
for(字符串s1:arr){
//获取数组元素
char[]c1=s1.toCharArray();
//检查数组元素长度是否与输入字符串长度匹配
如果(c1.length==c.length){
//将每次出现的字符计数到字母表数组中
int[]字符=新int[26];
int[]diff=新的int[26];
用于(字符k1:c1){
字符[k1-'a']++;
差异[k1-'a']++;
}
//通过使用map进行检查来减少计数
for(字符k:m.keySet()){
diff[k-'a']=chars[k-'a']-m.get(k);
}
布尔有效=真;
int不匹配=0;
int notzeros=0;
int-diffInS1=0;
//从字符数组中获取每个元素
对于(int i=0;i 1){
//检查值是否不匹配
如果(不匹配*-1!=ch){
有效=错误;
打破
}
}
如果(字符[i]>0){
diffInS1++;
}
//获取不匹配计数
失配=ch;
}
//如果非零元素大于2,则可以忽略此数组元素
如果(非零>2 | | diffInS1==2){
有效=错误;
打破
}
}
//检查可能的解决方案。
if(有效的&¬zeros>0){
匹配++;
}
}
}
我将提供类似的方法。让我们分析两个字符串何时“替换一个字符及其所有匹配项后匹配字符串”。假设我们有两个char
count的映射。现在我们需要计算它们的差异。当两个左映射有一个条目且计数器相等时,两个字符串匹配
让我们做一个例子<代码>aabbcd将创建地图:
a -> 2
b -> 4
c -> 1
d -> 1
aabbxdbb
将创建:
a -> 2
b -> 4
x -> 1
d -> 1
区别在于:
b -> 1
c -> -1
第一张地图将保留:
c -> 1
第二张地图:
x -> 1
因此,这两个人是匹配的。让我们看看如何写这个
首先,这是获取此地图的方法:
private static Map<Character, Integer> getMap(String s) {
Map<Character, Integer> result = new HashMap<>();
for (char c : s.toCharArray()) {
if (result.containsKey(c)) {
result.put(c, result.get(c) + 1);
} else {
result.put(c, 1);
}
}
return result;
}
我们得到了输出:
aabbcdbb and aabbcdbbb cannot be replaced.
aabbcdbb and aabbcdb cannot be replaced.
aabbcdbb and aabbxdbb can be replaced. Replace 1 instances of c with 1 instances of x
aabbcdbb and aabbbdbb can be replaced. Replace 1 instances of c with 1 instances of b
aabbcdbb and aacccdcc can be replaced. Replace 4 instances of b with 4 instances of c
aabbcdbb and ddbbcdbb can be replaced. Replace 2 instances of a with 2 instances of d
aabbcdbb and eebbcdbb can be replaced. Replace 2 instances of a with 2 instances of e
Replacables count: 5
调试。所以,在你的测试中,你期望结果是1,但你得到了2。当您调试导致结果计数的两种情况时,一种是100%正确,另一种是错误的吗?为什么会出现不正确的匹配?@jarmod,我发现我采用的方法本身是错误的,我已经调试了代码。这两种解释相互矛盾。在第一种情况下,您只替换出现的一些字符,这是正常的,但在第二种情况下,这是不正常的。如果像上面解释的那样(所有发生),那么第一个示例的答案应该是1。@maraca,是的,我错过了。这是在一次访谈中被问到的,对于这两种情况,预期输出与我的样本输入中给出的相同。我对如何获得输出的理解不正确。@学习者您还在寻找答案吗?(请将我的目光从代码上移开,我希望您能简洁地描述如何从字符直方图获得真值替换匹配。)
private static Predicate<String> getPredicate(String s) {
Map<Character, Integer> sMap = getMap(s);
Predicate<String> p = s1 -> {
Map<Character, Integer> s1Map = getMap(s1);
Map<Character, Integer> sMapCopy = getMap(s);
for (Map.Entry<Character, Integer> kvp : sMap.entrySet()) {
if (s1Map.containsKey(kvp.getKey())) {
if (s1Map.get(kvp.getKey()) < kvp.getValue()) {
sMapCopy.put(kvp.getKey(), kvp.getValue() - s1Map.get(kvp.getKey()));
s1Map.remove(kvp.getKey());
} else if (kvp.getValue() < s1Map.get(kvp.getKey())) {
s1Map.put(kvp.getKey(), s1Map.get(kvp.getKey()) - kvp.getValue());
sMapCopy.remove(kvp.getKey());
} else {
sMapCopy.remove(kvp.getKey());
s1Map.remove(kvp.getKey());
}
}
}
boolean result = sMapCopy.size() == 1 && s1Map.size() == 1;
if (result) {
for (Map.Entry<Character, Integer> kvp : sMapCopy.entrySet()) {
for (Map.Entry<Character, Integer> kvp1 : s1Map.entrySet()) {
System.out.println(s + " and " + s1 + " can be replaced. Replace " + kvp.getValue() + " instances of " + kvp.getKey() + " with " + kvp1.getValue() + " instances of " + kvp1.getKey());
}
}
} else {
System.out.println(s + " and " + s1 + " cannot be replaced.");
}
return result;
};
return p;
}
String[] strings = {"aabbcdbbb", "aabbcdb", "aabbxdbb", "aabbbdbb", "aacccdcc", "ddbbcdbb", "eebbcdbb"};
long result = Arrays.stream(strings).filter(getPredicate("aabbcdbb")).count();
System.out.println("Replacables count: " + result);
aabbcdbb and aabbcdbbb cannot be replaced.
aabbcdbb and aabbcdb cannot be replaced.
aabbcdbb and aabbxdbb can be replaced. Replace 1 instances of c with 1 instances of x
aabbcdbb and aabbbdbb can be replaced. Replace 1 instances of c with 1 instances of b
aabbcdbb and aacccdcc can be replaced. Replace 4 instances of b with 4 instances of c
aabbcdbb and ddbbcdbb can be replaced. Replace 2 instances of a with 2 instances of d
aabbcdbb and eebbcdbb can be replaced. Replace 2 instances of a with 2 instances of e
Replacables count: 5