JavaScript中如何正确统计唯一辅音数量?代码问题排查
问题
开发项目时遇到以下问题:接收用户输入并存入数组,判断字符为元音或辅音,元音统计正常,但辅音计数存在两个问题:
- 与元音比对统计辅音时会出现重复计数;
- 不知道如何仅统计每个辅音一次。
附上当前代码:
<!DOCTYPE html> <html lang="ca"> <head> <meta charset="utf-8" /> <title>DAW0612-Pràctica 08</title> <link href="imatges/favicon.ico" type="image/ico" rel="Shortcut Icon"/> <link href="codi/estil.css" rel="stylesheet" type="text/css" /> </head> <body> <header>A l'inrevés</header> <br /> <div id="missatge"></div> <h3 id="paraula"></h3> <h4 id="caracters"></h4> <p id="consonants"></p> <p id="vocals"></p> <p id="espais"></p> <p id="especials"></p> <script> /************ COMENÇEU AQUÍ EL VOSTRE CODI ***************************************************************/ //variables var frase =[10]; var fraseinreves=[10]; var dump; var vocales=["a","e","i","o","u"]; var espais = 0; var j=0; var vocals = 0; var consonants = 0; //programa frase = window.prompt("Dame una frase cualquiera"); lfrase = frase.length; for (let i = frase.length -1; i >=0; i--){ //guardamos la frase al reves dentro de la nueva array fraseinreves[j]=frase[i]; // resultado += frase[i]; if (frase[i] == " "){ espais++; } //incrementamos el contador de la array nueva j++; } for (let i = 0; i < frase.length; i ++){ //guardamos los caracteres uno por uno del array a la constante char const char = frase[i]; //window.alert(char); window.alert(char); //creamos un loop para recorrer la array que contiene las vocales for (let j = 0; j < vocales.length; j++){ //SI EL CONTENIDO DE CHAR, ES IGUAL A ALGUNA VOCAL (ESTAS SE RECORREN EN EL SEGUNDO LOOP), entonces: if(char == vocales[j]){ window.alert(char); vocals++; } } //contador para las consonantes. } /************ NO TOQUEU EL SEGÜENT CODI ***************************************************************/ document.getElementById("missatge").innerHTML = fraseinreves; document.getElementById("paraula").innerHTML = "Paraula o frase original: <span>" + frase + "</span>"; document.getElementById("caracters").innerHTML = "Nombre de caràcters: " + lfrase; document.getElementById("consonants").innerHTML = "Consonants: " + consonants; document.getElementById("vocals").innerHTML = "Vocals: " + vocals; document.getElementById("espais").innerHTML = "Espais en blanc: " + espais; document.getElementById("especials").innerHTML = "Lletres ñ o ç: " + especial; </script> <noscript> El seu navegador no accepta Javascript, si us plau actualitzis a una versió mes moderna. </noscript> <br /> <footer> 2016 Departament d'Informàtica - INS LA PINEDA - BADALONA<span>DAW M06-Desenvolupament Web en Entorn Client</span> </footer> </body> </html>
注:不使用includes()这类方法,通过基础逻辑排查问题、提升编程思维。
解决方案
一、解决辅音重复计数问题
原代码没有正确的辅音判断逻辑:如果直接在元音循环后加consonants++,每个字符会因为遍历5个元音而被重复计数5次。正确逻辑如下:
- 给每个字符标记是否为元音;
- 遍历完所有元音后,确认该字符不是元音、不是空格、且是有效字母,再执行一次辅音计数。
具体修改:
- 对每个字符初始化
isVowel为false; - 匹配到元音时将
isVowel设为true,并跳出循环减少无效遍历; - 循环结束后,根据
isVowel的状态判断是否为辅音。
二、实现辅音去重统计
要统计每个辅音仅一次,需要用数组记录已统计过的辅音:
- 初始化空数组
seenConsonants; - 确认字符是辅音后,遍历该数组检查是否已存在;
- 若不存在,则将字符加入数组并增加计数。
修改后的核心代码
替换原字符遍历循环部分:
// 新增数组记录已统计的辅音 var seenConsonants = []; // 初始化特殊字符计数变量 var especial = 0; // 修正frase的错误初始化,原数组定义会被后续prompt覆盖 var frase; frase = window.prompt("Dame una frase cualquiera"); lfrase = frase.length; // 反转字符串逻辑保留不变(略) for (let i = 0; i < frase.length; i ++){ const char = frase[i].toLowerCase(); // 统一转小写,避免大小写重复统计 let isVowel = false; // 遍历元音数组判断是否为元音 for (let j = 0; j < vocales.length; j++){ if(char == vocales[j]){ isVowel = true; vocals++; break; // 匹配到元音后立即跳出循环,提升效率 } } // 统计特殊字符ñ/ç if (char === 'ñ' || char === 'ç') { especial++; } // 判断是否为辅音:非元音、非空格、是有效字母(含ñ/ç) if (!isVowel && char !== " " && /[a-zçñ]/.test(char)) { let isAlreadyCounted = false; // 遍历已统计数组检查是否重复 for (let k = 0; k < seenConsonants.length; k++) { if (char === seenConsonants[k]) { isAlreadyCounted = true; break; } } // 未重复则加入数组并计数 if (!isAlreadyCounted) { seenConsonants.push(char); consonants++; } } }
额外优化说明
- 原代码中
frase = [10];是无效初始化,后续prompt会把它覆盖为字符串,直接改为var frase;即可; - 加入
toLowerCase()统一字符大小写,避免同一辅音因大小写被重复统计; - 补充了
especial变量的初始化和统计逻辑,解决原代码中变量未定义的错误; - 元音匹配时加入
break,减少不必要的循环遍历。
内容的提问来源于stack exchange,提问作者user17725739
相关产品推荐
相关产品推荐

