制作两个字符串字谜
Posted
技术标签:
【中文标题】制作两个字符串字谜【英文标题】:make two strings anagrams 【发布时间】:2018-06-07 20:27:44 【问题描述】:我解决了黑客等级的挑战。它关于如何字谜。我给了两个字符串输入,我必须找到...
打印一个整数,表示您必须删除的字符数,以使两个字符串相互变位。
我已经检测到它是否是字谜和差异。但现在可以做剩下的没有任何想法。请帮助。
function main()
var a = readLine();
var b = readLine();
var sum1 = 0 ;
var sum2 = 0 ;
for (var i= 0; i<= a.length-1; i++ )
sum1 = sum1 + a.charCodeAt(i);
console.log(sum1);
for (var i= 0; i<= b.length-1; i++ )
sum2 = sum2 + b.charCodeAt(i);
console.log(sum2);
if(sum1== sum2)
console.log("anagrams");
else
console.log("not anagram");
var diff = sum1 - sum2;
console.log(diff);
/// what to do now ?
【问题讨论】:
不是确定您了解如何完成它的编码挑战的一部分吗?当其他人为您回答时,有点违背了目的..... @Claies 虽然这是真的,但在大多数情况下,您可能会想出一个几乎正确的解决方案,但一个小错误会使您无法获得输出。在这种情况下,类似上述答案的参考非常有帮助。 【参考方案1】:如果您仍在寻找合理的解决方案,我已经在hackerRank 上使用对象方法计算字母的频率解决了这个问题。
function makeAnagrams(a,b)
let charA=buildcharMap(a)
let charB=buildcharMap(b)
let characters=[]
let counter=0
for(let char in charA)
if(charA[char] && charB[char])
if(charA[char]===charB[char]) //same frequency
continue;
else
if(charA[char]>charB[char])
counter=counter+ charA[char]-charB[char]
else
counter=counter+ charB[char]-charA[char]
else
counter=counter+charA[char]
for(let char in charB)
if(charB[char] && charA[char]===undefined)
counter=counter+charB[char]
return counter;
function buildcharMap(str)
var charMap=
for(let char of str)
if (charMap[char]===undefined)
charMap[char]=1
else
charMap[char]+=1
return charMap
console.log(makeAnagrams('cde','abc'))
【讨论】:
【参考方案2】:我已经在hackerearth上解决了这个问题,我采取了稍微不同的方法。
我在这段代码中所做的是检查所有字符,如果字符串中的两个字符相同,则用“@”符号替换字符,然后我计算其中一个字符串中的所有“@”符号即被修改,然后从两个字符串的总长度中减去该计数乘以 2 的值(因为...它们在两个字符串中相似)。
这是我的代码,希望你能把它转换成javascript。 ->
import java.util.Scanner;
public class Anagrams
public static void main(String[] args)
Scanner scanner = new Scanner(System.in);
int Testcases = scanner.nextInt();
String[] str1 = new String[1000];
String[] str2 = new String[1000];
// Taking input
for (int i = 0; i < Testcases; i++)
str1[i] = scanner.next().toLowerCase();
str2[i] = scanner.next().toLowerCase();
// For Total Length of both strings
int TotalLength[] = new int[Testcases];
// For counting "@" signs
int count[] = new int[Testcases];
// Loop through TestCases
for (int i = 0; i < Testcases; i++)
TotalLength[i] = str1[i].length() + str2[i].length();
for (int j = 0; j < str1[i].length(); j++)
for (int k = 0; k < str2[i].length(); k++)
// If both characters are similar, then replace those characters with "@" signs
if (str1[i].charAt(j) == str2[i].charAt(k))
str1[i] = str1[i].replaceFirst(Character.toString(str1[i].charAt(j)),"@");
str2[i] = str2[i].replaceFirst(Character.toString(str2[i].charAt(k)),"@");
// Counting "@" signs from one string
for (int i = 0; i < Testcases; i++)
count[i] = 0;
char[] c1 = str1[i].toCharArray();
for (char c: c1)
if(c == '@')
count[i]++;
// Output
for (int i = 0; i < Testcases; i++)
System.out.println(TotalLength[i] - 2*count[i]);
scanner.close();
【讨论】:
【参考方案3】:您实际上只是在寻找后期频率差异的总和。您可以将频率计入 26 项数组(规则告诉您只有小写数字)。然后从另一个项目中减去每个数组,但项目并将整个事情相加。好像只需要四行代码:
function makeAnagram(a, b)
const makeCountArray = (str) => [...str].reduce((a, c) => (a[c.charCodeAt(0) - 97]++, a), Array(26).fill(0))
let a1 = makeCountArray(a)
let a2 = makeCountArray(b)
return a1.reduce((a, c, i) => a + Math.abs(c - a2[i]), 0)
// test case expected: 30
let count = makeAnagram('fcrxzwscanmligyxyvym', 'jxwtrhvujlmrpdoqbisbwhmgpmeoke')
console.log(count)
【讨论】:
这绝对比我想象的要短。似乎它需要“减少”的高级知识。减去 97 有什么意义? @马克迈耶 @UgurYilmaz 97 是a
的值。这确保了数组索引从零开始。 reduce
需要一些练习并习惯,但一旦你这样做了,它就是 javascript 中最有用的功能之一。
你有没有推荐我可以用reduce练习的平台或教程? @马克迈耶
不确定@UgurYilmaz。 MDB 有一个很好的概述:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…【参考方案4】:
这是使用每个字符串中所有 26 个字母的 Map() 的另一种方法
function makeAnagram(a, b)
let result = 0;
const alphabets = 'abcdefghijklmnopqrstuvwxyz'.split('');
const getCharCountMap = str =>
const strArray = str.split('');
let charMap = new Map();
alphabets.forEach(alphabet => charMap.set(alphabet, 0));
strArray.forEach(letter => charMap.set(letter, charMap.get(letter) + 1));
return charMap;
;
const aMap = getCharCountMap(a);
const bMap = getCharCountMap(b);
alphabets.forEach(alphabet =>
result = result + Math.abs(aMap.get(alphabet) - bMap.get(alphabet));
);
return result;
【讨论】:
以上是关于制作两个字符串字谜的主要内容,如果未能解决你的问题,请参考以下文章