2017-01-19 2 views
1

Я пытаюсь переписать эту программу поиска частоты в Javascript. Вот код Java:Использование кодов символов для получения частоты слов в строке, JavaScript

public class frequency { 
    public static void main(String[] args){ 
     String S = "Temple University"; 
     int[] p = new int[256]; 
     for (char c :S.toCharArray()) { 
      p[c]++; 
      System.out.println(c +" shows up "+p[c] + " times"); 
     } 

Выход:

T shows up 1 times 
e shows up 1 times 
m shows up 1 times 
p shows up 1 times 
l shows up 1 times 
e shows up 2 times 
    shows up 1 times 
U shows up 1 times 
n shows up 1 times 
i shows up 1 times 
v shows up 1 times 
e shows up 3 times 
r shows up 1 times 
s shows up 1 times 
i shows up 2 times 
t shows up 1 times 
y shows up 1 times 

Однако моя реализация JavaScript не работает на всех:

function frequency(){ 
    s = "Temple University"; 
    str = s.split(''); 
    p = []; 
    p.length = 256; 
    console.log("start"); 
    for(c in str){ 
    p[c]++; 
    console.log("inside" + c); 
    console.log(String.fromCharCode(c) + " shows up " + p[c] + "times"); 
    } 
} 

Это поздно я пытался фигуры почему этот код JavaScript не работает, поэтому я сожалею, если этот пост кажется неполированным.

ответ

1

Основная причина, по которой это не работает, заключается в том, что для циклов в Javascript работают по-разному, чем в Java. В Javascript, а for-in цикл повторяется через свойства объекта, а не индексы массива или строки, так, а не for-in, вы хотели бы использовать простой for цикл, например, так:

function getFrequencies(string) { 
    if (typeof(string) !== 'string') { 
     throw new Error('string argument is not of type string.'); 
    } 

    var str = string.split(''); 
    var frequencies = {}; 
    for (var c = 0; c < str.length; c++) { 
     var charCode = String.fromCharCode(str[c]); 
     if (!frequencies[charCode]) { 
      frequencies[charCode] = 1; 
     } else { 
      frequencies[charCode]++; 
     } 
    } 

    return frequencies; 
} 

пару советов: вы хотели бы использовать простой объект ({}) вместо массива ([]), учитывая, что вы считаете уникальные значения. Во-вторых, нет необходимости объявлять длину массива в Javascript - массивы автоматически изменяются по мере их роста, а свойство length - в любом случае.

+0

Мне нравится понимание, которое дает ваш ответ, однако, когда я запускаю ваш код, все возвращается с частотой 1? Также вы могли бы подробнее рассказать о том, почему объект должен использоваться по массиву в этом случае. Почему объект лучше подходит для подсчета уникальных значений, есть ли преимущества в производительности для этого? – coderrick

+0

Одной из основных причин использования объекта является то, что массивы обычно используются в качестве коллекций, которые должны быть добавлены с помощью 'push' и' unshift', а затем повторяются с помощью цикла 'for' или' forEach'. Поэтому массив рассматривается как группа значений, каждая из которых имеет последовательный индекс. То, как вы это делаете, индексы не обязательно будут последовательными, и поэтому невозможно полноценно перебирать массив. Производительность на самом деле не проблема. – furkle

+0

@coderrick Кроме того, в коде была небольшая опечатка - теперь она должна работать. – furkle

1

Вы можете манипулировать строку непосредственно в виде массива и необходим безопасная проверка для появления символов еще присвоить значение 1.

Так использовать цикл для перебора всей строки может извлечь символ как с [индексом] при использовании р [char] для частоты появления.

образец кода следующим образом

function frequency(){ 
 
    s = "Temple University"; 
 
    p = []; 
 
    console.log("start"); 
 
    for(var i=0;i<s.length;i++){ 
 
    if(!p[s[i]]){ 
 
     p[s[i]] = 1; 
 
    }else{ 
 
     p[s[i]]++; 
 
    } 
 
    console.log(s[i] + " shows up " + p[s[i]] + "times"); 
 
    } 
 
} 
 

 
frequency()

1

делает эту работу для вас? Если да, то вы просто не были ссылки на charCode, но индекс буквы в строке ..

function frequency() { 
 
\t s = "Temple University"; 
 
\t str = s.split(''); 
 
\t p = []; 
 
\t p.length = 256; 
 
\t console.log("start"); 
 
\t for (c in str) { 
 
\t \t var curChar = str[c]; 
 
\t \t var charCode = curChar.charCodeAt(); 
 
\t \t p[charCode] ? p[charCode]++ : p[charCode] = 1; 
 

 
\t \t console.log(curChar + " shows up " + p[charCode] + " time(s)"); 
 
\t } 
 
} 
 

 
frequency()

0

Вы можете сделать следующим образом;

var s = "Temple University", 
 
fmap = Array.prototype.reduce.call(s,(p,c) => (p[c] ? p[c]++ : p[c] = 1,p),{}); 
 
for(var i in fmap) console.log(i, "shows up", fmap[i],"times.");

Мы используем функтор массива Array.prototype.reduce() через строку с помощью метода Function .call(). Таким образом, первый аргумент, переданный в .call(), представляет собой строку s (обозначение вызываемого контекста) и обратный вызов ((p,c) => (p[c] ? p[c]++ : p[c] = 1,p)) для второго аргумента, который должен быть вызван для каждого элемента (символа) строки. Функтор .reduce() использует пустой объект {} как начальное значение, которое будет присвоено p, тогда как c будет присвоено первому символу в первом повороте.Он будет генерировать карту, называемую fmap like;

{ T: 1, 
    e: 3, 
    m: 1, 
    p: 1, 
    l: 1, 
    ' ': 1, 
    U: 1, 
    n: 1, 
    i: 2, 
    v: 1, 
    r: 1, 
    s: 1, 
    t: 1, 
    y: 1 } 

Затем for in цикл проходит по клавишам карты и мы выводим полученные данные по console.log() в инструкции.

+0

Спасибо за приятное функциональное и несколько монадическое решение. Однако я не понимаю, какой код вы могли бы разработать? Каково значение использования flatmap (я зеленый, когда дело доходит до функционального программирования). Также вы знаете какие-либо хорошие блоги для изучения функционального программирования звука в JavaScript? – coderrick