如何按字符出现顺序对字符串进行排序?

huangapple go评论64阅读模式
英文:

How do I sort characters of a string by appearance order?

问题

我有以下的代码:

function main() {
  let input = prompt("输入一个字符串:").toLowerCase().replace(/\s/g, "");
  let process = "";

  for (let i = 0; i < input.length; i++) {
    let word = input[i];
    let repeatWord = "";
    for (let j = 0; j < word.length; j++) {
      repeatWord += word[j].repeat(j + 1);
    }
    process += repeatWord;
  }
  console.log(process);
}

如何按照字符首次出现的顺序对字符串进行排序?

例如,如果我输入字符串:"Learning Center",则预期结果应为:"leeearrnnigct"。

英文:

I have the following code:

function main() {
  let input = prompt(&quot;Enter a string:&quot;).toLowerCase().replace(/\s/g, &quot;&quot;);
  let process = &quot;&quot;;

  for (let i = 0; i &lt; input.length; i++) {
    let word = input[i];
    let repeatWord = &quot;&quot;;
    for (let j = 0; j &lt; word.length; j++) {
      repeatWord += word[j].repeat(j + 1);
    }
    process += repeatWord;
  }
  console.log(process);
}

How do I sort the characters of the string by order of first appearance?

For example, if I enter the string: &quot;Learning Center&quot;, then the expected result should be &quot;leeearrnnigct&quot;.

答案1

得分: 1

使用Map来存储字符串中所有字符的计数器。然后,由于Map保留插入顺序,您可以简单地遍历计数器,并使用每个键的值通过字符串repeat()方法和数组join()方法重新生成字符串。

function appearanceSort(str) {
  str = str.toLowerCase().replace(/\s/g, "");

  const counter = new Map();
  for (const char of str) {
    if (counter.has(char)) {
      counter.set(char, counter.get(char) + 1);
    } else {
      counter.set(char, 1);
    }
  }

  const strArr = [];
  for (const [key, value] of counter) {
    strArr.push(key.repeat(value));
  }

  return strArr.join("");
}

console.log(appearanceSort("Learning Center")); // leeearrnnigct

然而,上面的实现很可能不会按预期处理任意的Unicode字符。要支持字形簇,您可以使用诸如grapheme-splitter或浏览器内置的Intl.Segmenter等库,示例如下:

function appearanceSort(str) {
  str = str.toLowerCase().replace(/\s/g, "");

  const segments = Array.from(new Intl.Segmenter().segment(str)).map(({ segment }) => segment);

  const counter = new Map();
  for (const char of segments) {
    if (counter.has(char)) {
      counter.set(char, counter.get(char) + 1);
    } else {
      counter.set(char, 1);
    }
  }

  const strArr = [];
  for (const [key, value] of counter) {
    strArr.push(key.repeat(value));
  }

  return strArr.join("");
}

console.log(appearanceSort("&#128104;‍&#128104;‍&#128103;‍&#128102; Learning &#128104;‍&#128104;‍&#128103;‍&#128102; Center")); // &#128104;‍&#128104;‍&#128103;‍&#128102;&#128104;‍&#128104;‍&#128103;‍&#128102;leeearrnnnigct

注意: Intl.Segmenter当前不受Firefox支持。使用Intl中的&quot;Segmenter&quot;来检查浏览器支持并有条件地应用一些后备行为。

英文:

Use a Map to store a counter of all the characters in your string. Then, since Map preserves insertion order, you can simply iterate through the counter and use each key’s value to regenerate the string via the String repeat() method and the Array join() method.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function appearanceSort(str) {
  str = str.toLowerCase().replace(/\s/g, &quot;&quot;);

  const counter = new Map();
  for (const char of str) {
    if (counter.has(char)) {
      counter.set(char, counter.get(char) + 1);
    } else {
      counter.set(char, 1);
    }
  }

  const strArr = [];
  for (const [key, value] of counter) {
    strArr.push(key.repeat(value));
  }

  return strArr.join(&quot;&quot;);
}

console.log(appearanceSort(&quot;Learning Center&quot;)); // leeearrnnigct

<!-- end snippet -->

However, the implementation above most likely won't work as expected with arbitrary unicode characters. To support grapheme clusters, you can use a library such as grapheme-splitter, or the browser built-in Intl.Segmenter, which looks like so:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function appearanceSort(str) {
  str = str.toLowerCase().replace(/\s/g, &quot;&quot;);

  const segments = Array.from(new Intl.Segmenter().segment(str)).map(({
    segment
  }) =&gt; segment);

  const counter = new Map();
  for (const char of segments) {
    if (counter.has(char)) {
      counter.set(char, counter.get(char) + 1);
    } else {
      counter.set(char, 1);
    }
  }

  const strArr = [];
  for (const [key, value] of counter) {
    strArr.push(key.repeat(value));
  }

  return strArr.join(&quot;&quot;);
}

console.log(appearanceSort(&quot;&#128104;‍&#128104;‍&#128103;‍&#128102; Learning &#128104;‍&#128104;‍&#128103;‍&#128102; Center&quot;)); // &#128104;‍&#128104;‍&#128103;‍&#128102;&#128104;‍&#128104;‍&#128103;‍&#128102;leeearrnnnigct

<!-- end snippet -->

Note: Intl.Segmenter is currently not supported in Firefox. Use &quot;Segmenter&quot; in Intl to check for browser support and conditionally apply some fallback behavior.

答案2

得分: 0

我的方法是创建一个包含所有唯一字符的数组。然后遍历它,计算每个字符有多少个兄弟,然后重复该字符出现的次数。

英文:

My approach would be to create an array with all unique characters. Then iterate over it and count how many siblings each character has and then repeat the character as often as it appears.

function main(input: string) {
    const arr = input.toLocaleLowerCase().replace(/[ ]/g, &#39;&#39;).split(&quot;&quot;);
    let uniqueLetters = [...new Set(arr)]
    let word = &quot;&quot;;
    for (let i = 0; i &lt; uniqueLetters.length; i++) {
        const letter = uniqueLetters[i];   
        const letterCount = arr.filter((l) =&gt; l == letter).length;
        word += letter.repeat(letterCount)
    }
    return word;
}

console.log(main(&quot;Learning Center&quot;)) // prints: leeearrnnnigct

答案3

得分: 0

这是另一个版本。这个版本将保留空格并区分大小写字母:

<!-- begin snippet:js console:true -->
<!-- language:lang-js -->
const str = "Learning Center".split(""),
      freq = {};
str.forEach(c => freq[c] = (freq[c]??0) + 1);
const res = str.map(c => {
 let s = c.repeat(freq[c]);
 freq[c] = 0;
 return s
}).join("");

console.log(res);

<!-- end snippet -->

如果您希望不区分大小写且没有空格的解决方案,只需将其修改为:

<!-- begin snippet:js console:true -->
<!-- language:lang-js -->
const str = "Learning Center".toLowerCase().replaceAll(" ","").split(""),
      freq = {};
str.forEach(c => freq[c] = (freq[c]??0) + 1);
const res = str.map(c => {
 let s = c.repeat(freq[c]);
 freq[c] = 0;
 return s
}).join("");

console.log(res);

<!-- end snippet -->
英文:

Here is yet another version. This one will keep blanks and distinguish between upper/lower case letters:

<!-- begin snippet:js console:true -->
<!-- language:lang-js -->
const str="Learning Center".split(""),
freq={};
str.forEach(c=>freq[c]=(freq[c]??0)+1);
const res=str.map(c=>{
let s=c.repeat(freq[c]);
freq[c]=0;
return s
}).join("");

console.log(res);

<!-- end snippet -->

If you prefer a case insensitive solution without blanks then simply modify it to:

<!-- begin snippet:js console:true -->
<!-- language:lang-js -->
const str="Learning Center".toLowerCase().replaceAll(" ","").split(""),
freq={};
str.forEach(c=>freq[c]=(freq[c]??0)+1);
const res=str.map(c=>{
let s=c.repeat(freq[c]);
freq[c]=0;
return s
}).join("");

console.log(res);

<!-- end snippet -->

答案4

得分: -1

当你遍历字符串中的每个字符时,创建一个新的索引,然后使用第三个变量来交换字符。

你可以尝试下面的代码。

function suffle(target) {
  var chars = target.split("");
  var length = chars.length;

  for (var i = length - 1; i > 0; i--) {
    var j = Math.floor(Math.random() * (i + 1));
    var tmp = chars[i];
    chars[i] = chars[j];
    chars[j] = tmp;
  }

  return chars.join("");
}

console.log(suffle("hello"));
英文:

When you run through each characters in the string, create a new index and then use a third variable to swap the characters.

You can try the code below.

function suffle(target) {
  var chars = target.split(&quot;&quot;);
  var length = chars.length;

  for (var i = length - 1; i &gt; 0; i--) {
    var j = Math.floor(Math.random() * (i + 1));
    var tmp = chars[i];
    chars[i] = chars[j];
    chars[j] = tmp;
  }

  return chars.join(&quot;&quot;);
}

console.log(suffle(&quot;hello&quot;));

huangapple
  • 本文由 发表于 2023年6月22日 13:10:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76528753.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定