🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

5回答

5097閲覧

JavaScript:正規表現を使わずに半角数字を漢数字に変換したい

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2017/08/01 03:52

編集2017/08/01 04:17

###前提・実現したいこと
JavaScriptで"正規表現を使わず"に、テキストエリアに入力された
半角数字を漢数字に変換し、入力欄の下に表示したい。

###該当のソースコード

<section> <p>数字を入力してください。漢数字に変換します。</p> <form> <input type="text" id="num"/> <input type="button" value="変換" onclick="convert()"/> </form> <p id="result">ここに結果を表示します。</p> </section>
function toKanji(n) { var th = ["","千","二千","三千","四千","五千","六千","七千","八千","九千"]; var h = ["","百","二百","三百","四百","五百","六百","七百","八百","九百"]; var t = ["","十","二十","三十","四十","五十","六十","七十","八十","九十"]; var o = ["","一","二","三","四","五","六","七","八","九"]; var str = ''; var s = ''; var m = ''; if (n == 0) { return '零'; } else if (n < 0 || isNaN(n)) { return alert('漢数字に変換できません。'); } else { for (var i = 0; i < n.length; i++) { s = n.substr(,); // th = th [ Math.floor(s / 1000) ]; h = h [ Math.floor(s / 100) % 10 ]; t = t [ Math.floor(s / 10) % 10 ]; o = o [ s % 10 ]; m = th + h + t + o ; str += m ; } return str; } } function convert() { var n = document.getElementById('num').value; var result = document.getElementById('result'); result.innerHTML = toKanji(n); }

###補足情報(言語/FW/ツール等のバージョンなど)
文系の学生です。独学でJavaScriptを勉強をしています。
上記のHTMLを元に色々試してみたのですが、全然できなくて悩んでおります。

ルールとして、下記の事項を守ること。
1)桁は 一、十、百、千、万、億、兆、京・・・・無量大数 まで。
2)一万未満の千の位には、常に一は表示しない。
3)一万以上の4桁区切り内での千の位は、一千丁度のときだけ一を表示する。

123456789 = 一億二千三百四十五万六千七百八十九
10010000 = 千一万
10001 = 一万一
1001 = 千一

どうすればできるのか考えてみたのですが、
4桁ずつ切り出し漢数字へ変換
→4桁ごとに桁を追加
→if文で4桁の中身が空欄だったら桁つけない?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kei344

2017/08/01 03:54

質問文のコードはコードブロックで囲んでいただけませんか? ```(バッククオート3つ)で囲み、前後に改行をいれるか、コードを選択して「<code>」ボタンを押すとコードブロックになります。ご自身で試されたコードを質問文に追記し、「何」が「どのように」わからないのか、コードのどの部分で詰まっているのかなどを具体的に追記されたほうが回答が望めると思います。
yambejp

2017/08/01 04:00

要求定義ができているなら実装するだけですよね?むしろ何がわからないでしょう?具体的にソースを例示してつまっているところを教えてください
otn

2017/08/01 04:01

めんどくさいだけで、難しさはないと思いますが、何が出来ないのでしょうか?
Lhankor_Mhy

2017/08/01 05:11

javascriptで取り扱える数値は2^53+1までなので、京以上の単位は表現できないと思います。
guest

回答5

0

この手のありがちなものは、WEB検索すればすぐ見つかります。

JavaScript 漢数字変換 - Google 検索

上記の2番目の

アラビア数字→漢数字変換(桁付き)する JavaScript - drk7jp

だと無量大数まで対応してます。

追記

ごめんなさい。

"正規表現を使わず"

という条件を見落としてました。
上記のリンク先は正規表現を使ってますね。

この条件を付けたのは、自分の勉強のためにということでしょうか。
ならば、もう少し自分で考えてみて、コードを書いて、
行き詰ったところ、想定通りにならないところをピンポイントで質問したほうが
スキルアップにつながるでしょう。

追記2

提示のコードはいいところまでいっています。
もっと効率的なコードもありますが、自分の学習のためということなので、提示のコードをなるべく活かしてアドバイスします。
まず、一気に一つの関数で無量大数までやろうとせずに、まずは4桁までの数値に千百十の桁を付加して変換する関数を作成するようにするといいでしょう。
提示のコードの一部を変更しました。テキストボックスに4桁以下の数を入力して、希望の結果になるのを確認してください。

js

1function toKanji4(n) { 2 var th = ["","千","二千","三千","四千","五千","六千","七千","八千","九千"]; 3 var h = ["","百","二百","三百","四百","五百","六百","七百","八百","九百"]; 4 var t = ["","十","二十","三十","四十","五十","六十","七十","八十","九十"]; 5 var o = ["","一","二","三","四","五","六","七","八","九"]; 6 var s = ''; 7 var m = ''; 8 9 if (n == 0) { 10 return '零'; 11 } else if (n < 0 || isNaN(n)) { 12 return alert('漢数字に変換できません。'); 13 } else { 14 s = n.substr(-4); 15 th = th [ Math.floor(s / 1000) ]; 16 h = h [ Math.floor(s / 100) % 10 ]; 17 t = t [ Math.floor(s / 10) % 10 ]; 18 o = o [ s % 10 ]; 19 m = th + h + t + o ; 20 return m; 21 } 22} 23 24function convert() { 25 var n = document.getElementById('num').value; 26 var result = document.getElementById('result'); 27 result.innerHTML = toKanji4(n); 28}

ほとんど自分で書いたコードですのでやっていることの意味は理解できますよね。
うまく動作することが確認できたら、次は、
末尾から4桁ずつ取り出して、上記の関数で変換させて、それに万、億、兆の桁を付加してつなげていく関数を作成すればいいことになります。トライしてみてください。

投稿2017/08/01 04:22

編集2017/08/01 13:23
hatena19

総合スコア34073

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/08/01 05:01

ご回答ありがとうございます。URLはすでに拝見したものでした、申し訳ございません。おっしゃる通り、勉強のため”正規表現を使わずに”という条件を課しております。 >もう少し自分で考えてみて、コードを書いて、行き詰ったところ、  想定通りにならないところをピンポイントで質問したほうがスキルアップにつながるでしょう。 みなさんは一般的にどのくらい考えられるのでしょうか?私は二日間、1日12時間考えていたのですが、参考までに教えていただけますと幸いです。また、コードは書いてあるところまでですでに行き詰っておりまして…、仮説自体が立てられていないという状況で…。もう少し勉強しないと皆さまに申し訳ないですね。すみません。
guest

0

なるべく短く書こうとしてみましたが……
4ケタに分割してロケールストリングに変換して配列にし、それぞれの要素に千百十をいれ、要素の間に兆億万の単位を入れる感じです。

javascript

1n = 1000000001203450; 2 3[...( 4 function* (n){ 5 while ( n >= 1 ){ 6 const remainder = n % 10000; 7 n = parseInt( n / 10000 ); 8 yield remainder; 9 } 10 } 11)(n)].map( 12 n => n.toLocaleString( 'ja-JP-u-nu-hanidec', {useGrouping: false} ).split('').reverse().map( 13 (d, i)=> { 14 if ( d == '〇' ) return ''; 15 if ( d == '一' ) return '一十百千'[i]; 16 return d + ' 十百千'[i]; 17 } 18 ).reverse().join('') 19).map( 20 (d, i)=> { 21 if ( d == '千' && i != 0 ) return d.replace( '千', '一千' ) + " 万億兆"[i]; 22 if ( d == '' ) return ''; 23 return d + " 万億兆"[i]; 24 } 25).reverse().join('').split(' ').join(''); 26 27/* 28一千兆百二十万三千四百五十 29*/

投稿2017/08/01 07:02

編集2017/08/01 07:40
Lhankor_Mhy

総合スコア36946

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lhankor_Mhy

2017/08/01 07:41

ルール2を満たしていなかったので修正しました。
guest

0

全部は見ていませんが……
まずはこのへんが怪しそうです。

javascript

1s = n.substr(,); //

追記:書いているうちに他の方の回答がついてかぶってしまいました。
このレベルの問題はデバッガでたやすく見つけ出せるはずなので、12時間一人で悩む前にまずは「ステップ実行」でしょう。

投稿2017/08/01 05:13

編集2017/08/01 05:17
KojiDoi

総合スコア13692

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/08/01 05:16

申し訳ございません。数字を4桁ずつ切り出して変換していこうとしていたのですが、どうやっていいか分からず、そのままにしておりました。
KojiDoi

2017/08/01 05:19

でしたら、まずはそこを質問されたら良かったと思います。質問のフォーカスは絞ったほうがいいです。
退会済みユーザー

退会済みユーザー

2017/08/01 05:29

質問をさらに絞ったほうが良かったんですね。はじめてだったとはいえ、もう少し他の方の投稿をちゃんと見て考えるべきでした。デバッガやステップ実行という言葉は知りませんでした。ありがとうございます!
guest

0

とりあえず元の方ですが以下でエラーです substrを何に使おうとしているのかよくわかりませんが
s = n.substr(,);
s = n.substr(",");

また以下のようにしてしまうと
th = th [ Math.floor(s / 1000) ];

var th = ["","千","二千","三千","四千","五千","六千","七千","八千","九千"];
のデータを上書きしてしまうので別の変数に入れるようにした方がいいです

投稿2017/08/01 05:06

date

総合スコア1820

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/08/01 05:12

substrでは、n.substr(~,4)という形にして、数字を4桁ずつ切り出して、変換していこうとしていました。上書きはしない方がいいんですね。別の変数に入れてみます。ありがとうございます。
guest

0

皆様の回答とても勉強になります。
別の言語ですが私も最近、半角英数字を漢数字に
変換するプログラムを作っていました。

私のやり方は
1.数字を1文字ずつ分解して、その数字の位(10^n)を交互に入れたリストを作る。
2.そのリストをキーに予め用意しておいた辞書から漢数字を持ってくる。
3.最後に例外的な変更を行う。
というものでした。

正確に動くかどうかは分かりません。

C#

1using System; 2using System.Collections.Generic; 3using System.Linq; 4 5namespace Kansuji 6{ 7 class Program 8 { 9 static String Trans(string key) 10 { 11 key = key.Replace("+0", ""); 12 13 if(new string[]{ "^5", "^9", "^13" }.Contains(key)) 14 { 15 key = "^1"; 16 } 17 else if(new string[]{ "^6", "^10", "^14" }.Contains(key)) 18 { 19 key = "^2"; 20 } 21 else if(new string[]{ "^7", "^11", "^15" }.Contains(key)) 22 { 23 key = "^3"; 24 } 25 26 Dictionary<string, string> trans = new Dictionary<string, string>(){ 27 {"1", "一"}, 28 {"2", "二"}, 29 {"3", "三"}, 30 {"4", "四"}, 31 {"5", "五"}, 32 {"6", "六"}, 33 {"7", "七"}, 34 {"8", "八"}, 35 {"9", "九"}, 36 {"^1", "十"}, 37 {"^2", "百"}, 38 {"^3", "千"}, 39 {"^4", "万"}, 40 {"^8", "億"}, 41 {"^12", "兆"}, 42 }; 43 44 return trans.ContainsKey(key) ? trans[key] : ""; 45 } 46 47 static void Main() 48 { 49 string input = Console.ReadLine(); 50 51 List<string> keys = new List<string>(); 52 53 bool zero = true; 54 55 for(int i = 0; i < input.Length; i ++) 56 { 57 if(input[i] != '0') 58 { 59 keys.Add(input[i].ToString()); 60 61 if(i != input.Length - 1) 62 { 63 keys.Add("^" + (input.Length - 1 - i).ToString()); 64 } 65 66 zero = false; 67 } 68 else 69 { 70 if(new int[] {4, 8, 12}.Contains(input.Length - 1 - i)) 71 { 72 if(!"^8^12".Contains(keys.Last())) 73 { 74 if(keys.Last().Contains("+0")) continue; 75 keys.Add("^" + (input.Length - 1 - i).ToString() + "+0"); 76 } 77 } 78 } 79 } 80 81 if(zero) 82 { 83 Console.WriteLine("〇"); 84 return; 85 } 86 87 Console.WriteLine(string.Join(", ", keys)); 88 89 string[] result = keys.Select(e => Trans(e)).ToArray(); 90 91 string[] _ans = string.Join("", result) 92 .Replace("一十", "十") 93 .Replace("一百", "百") 94 .Replace("一千", "千") 95 .ToCharArray() 96 .Select(c => c.ToString()) 97 .ToArray(); 98 99 for(int i = 0; i < _ans.Length; i ++) 100 { 101 if(input.Length < 5) continue; 102 103 if(i == 0 || "兆億".Contains(_ans[i - 1])) 104 { 105 if(i == _ans.Length - 1 || "兆億万".Contains(_ans[i + 1])) 106 { 107 if(_ans[i] == "千") _ans[i] = "一千"; 108 } 109 } 110 } 111 112 string ans = string.Join("", _ans); 113 114 Console.WriteLine(ans); 115 } 116 } 117}

追記

C#

1using System; 2using System.Collections.Generic; 3using System.Linq; 4 5namespace Kansuji 6{ 7 class Program 8 { 9 static string Trans(string input) 10 { 11 Dictionary<string, string> dic = new Dictionary<string, string>(){ 12 {"0", "〇"}, 13 {"1", "一"}, 14 {"2", "二"}, 15 {"3", "三"}, 16 {"4", "四"}, 17 {"5", "五"}, 18 {"6", "六"}, 19 {"7", "七"}, 20 {"8", "八"}, 21 {"9", "九"}, 22 }; 23 24 return dic[input]; 25 } 26 27 static List<string[]> Slice(string[] input) 28 { 29 input = input.Reverse().ToArray(); 30 31 List<string[]> result = new List<string[]>(); 32 33 int count = 0; 34 35 while(count + 4 <= input.Length) 36 { 37 string[] _t = new string[4]; 38 Array.Copy(input, count, _t, 0, 4); 39 result.Add(_t); 40 count += 4; 41 } 42 43 int rest = input.Length - count; 44 45 if(rest != 0) 46 { 47 string[] _r = new string[4]; 48 49 for(int i = 0; i < 4 - rest; i++) 50 { 51 _r[3 - i] = "0"; 52 } 53 54 Array.Copy(input, count, _r, 0, rest); 55 result.Add(_r); 56 } 57 58 59 for(int i = 0; i < result.Count; i++) 60 { 61 result[i] = result[i].Reverse().Select(e => Trans(e)).ToArray(); 62 } 63 64 result.Reverse(); 65 66 return result; 67 } 68 69 static void Main(string[] args) 70 { 71 string input = args[0]; 72 73 if(int.Parse(input) == 0) 74 { 75 Console.WriteLine("〇"); 76 return; 77 } 78 79 List<string[]> _list = Slice(input.ToCharArray().Select(e => e.ToString()).ToArray()); 80 81 for(int i = 0; i < _list.Count; i++) 82 { 83 string[] _c = _list[i]; 84 85 for(int j = 0; j < _c.Length; j++) 86 { 87 string _d = _c[j]; 88 89 if(_d == "〇") 90 { 91 _d = ""; 92 } 93 else if(_d == "一") 94 { 95 _d = "千百十一"[j].ToString(); 96 } 97 else 98 { 99 _d = j < 3 ? _d + "千百十"[j].ToString() : _d; 100 } 101 102 _c[j] = _d; 103 } 104 105 _list[i] = _c; 106 } 107 108 string[] _k = new string[]{ "", "万", "億", "兆" }; 109 110 List<string> result = new List<string>(); 111 112 _list.Reverse(); 113 114 for(int i = 0; i < _list.Count; i++) 115 { 116 string[] arr = _list[i]; 117 118 bool next_flag = true; 119 120 foreach(string s in arr) 121 { 122 if(s != "") next_flag = false; 123 } 124 125 if(next_flag) continue; 126 127 result.Add(_k[i]); 128 129 string[] check = arr.Where(e => e != "").ToArray(); 130 131 result.Add(check.Length == 1 && check[0] == "千" && i != 0 ? "一千" : string.Join("", arr)); 132 } 133 134 result.Reverse(); 135 136 Console.WriteLine(string.Join("", result)); 137 } 138 } 139}

投稿2017/08/01 16:50

編集2017/08/05 14:54
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問