paizaラーニング レベルアップ問題集 線形探索メニュー応用編 JavaScript CSV ファイル 2まとめ


# CSV ファイル 2
STEPを順番に解いていけばFINAL問題が解けます

## STEP: 1 文字の探索
文字列の中から特定の文字を探索します

https://paiza.jp/works/mondai/sequence_search_problems_advanced/sequence_search_problems_advanced__strings_step0

### 解答例

indexOfで一発です。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
const [s, c] = lines.slice(0);
console.log(s.indexOf(c) + 1);
```

## STEP: 2 文字のカウント
文字列に含まれる文字の頻度分析をおこないます

https://paiza.jp/works/mondai/sequence_search_problems_advanced/sequence_search_problems_advanced__strings_step1

### 解答例
sをfilterにかけ、lengthで文字数がわかります。アルファベットを順に調べていきます。

```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const s = lines[0].split("");
const alphabet = "abcdefghijklmnopqrstuvwxyz";

for (let i = 0; i < alphabet.length; i++) {
  console.log(s.filter(v => v === alphabet[i]).length);
}
```
## STEP: 3 部分文字列
文字列から特定の部分文字列の個数を計算します

https://paiza.jp/works/mondai/sequence_search_problems_advanced/sequence_search_problems_advanced__strings_step2

l,rを全探索してもよいですが、lだけ全探索した方が少し効率がよくなります。

ループを用いて l を全探索します。文字列 s の長さを n, 文字列 t の長さを m とおくと、 l は 0 以上 n - m + 1 未満をとります。

次に、 s の l 番目から連続する m 文字の文字列を作成します。この文字列が t と等しければ、答えを 1 増やします。

s の l 番目から連続する m 文字の文字列を作成する方法は２つあります。
1. for文
   変数を置いて、forループで変数に追加して作成します。
1. メソッド
  多くの言語では部分文字列を作成する機能が搭載されています。これを用いると簡潔に記述できます。JavaScriptには、`substr` 、 `substring` 、 `slice`などがありますが、`substr`は非推奨なので、使わない方がよいかもしれません。

### 解答例1(for文)
for文で文字列作成です。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//sの部分列がt
const [s, t] = lines.slice(0);

let ans = 0;//sの部分列でtと等しいものの個数
//sの先頭から調べる
for (let i = 0; i < s.length - t.length + 1; i++) {
  //for文で文字列作成
  let substr =  "";
  for (let j = 0; j < t.length; j++) {
    substr += s[i + j];
  }
  //作成文字列がtと等しいならカウント
  if (substr === t) {
    ans += 1;
  }
}
console.log(ans);
```

### 解答例2(メソッド)
メソッドで文字列作成です。sliceで解答していますが、substringでもできます。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//sの部分列がt
const [s, t] = lines.slice(0);

let ans = 0;//sの部分列でtと等しいものの個数
//sの先頭から調べる
for (let i = 0; i < s.length - t.length + 1; i++) {
  //メソッドで文字列作成
  if (s.slice(i, i + t.length) === t) { //sliceはsubstringでも可
    ans += 1;
  }
}
console.log(ans);
```

### 解答例3(異なる文字が含まれていたらカウントしない)
文字列を作成せず、異なる文字が含まれていたら、カウントしない、全て同じならカウントする、というやり方です。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//sの部分列がt
const [s, t] = lines.slice(0);

let ans = 0;//sの部分列でtと等しいものの個数
//sの先頭から調べる
for (let l = 0; l < s.length; l++) {
  let flag =  true;//sの部分列とtが等しいか
  for (let i = 0; i < t.length; i++) {
    if (s[l + i] !== t[i]) { //s!=tならfalse
      flag = false;
      break;
    }
  }
  if (flag) ans++;//s=tならtrueでans++
}
console.log(ans);
```

## STEP: 4 分割
文字列を特定の条件で分割します

https://paiza.jp/works/mondai/sequence_search_problems_advanced/sequence_search_problems_advanced__strings_step3

### 解答例
splitで分割してjoinで半角スペース区切りにします。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
console.log(lines[0].split(",").join(" "));
```

## STEP: 5 CSV ファイル 1
CSV 形式の文字を解析します

https://paiza.jp/works/mondai/sequence_search_problems_advanced/sequence_search_problems_advanced__strings_step4


### 解答例
split(",")でカンマで区切って配列にして、2列目がx以上か調べます。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [n, x] = lines[0].split(" ").map(Number);

for (let i = 1; i <= n; i++) {
  const s = lines[i].split(",").map(Number);
  if (s[1] >= x) {
    console.log(lines[i]);
  }
}
```
### 解答例(ワンライナー)
１文で解いてみました。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

console.log(
  lines.slice(1) //1行目以降を配列に
    .filter(line =>　//x以上を残す 
      line.split(",").map(Number)[1] >=  //sの2列目の値
      lines[0].split(" ").map(Number)[1] //x
    )
    .join("\n")//改行区切り
);
```
## FINAL問題 CSV ファイル 2
CSV 形式の文字を解析します

https://paiza.jp/works/mondai/sequence_search_problems_advanced/sequence_search_problems_advanced__strings_boss

STEP: 5 CSV ファイル 1の2列目をk列目にすればいいです。

```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [n, m, k, x] = lines[0].split(" ").map(Number);

for (let i = 1; i <= n; i++) {
  const s = lines[i].split(",").map(Number);
  if (s[k - 1] >= x) {
    console.log(lines[i]);
  }
}
```
### 解答例(ワンライナー)

const [n, m, k, x]を省けば、文は減りますが、文字数が多くなりそうなので、そのままです。

```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [n, m, k, x] = lines[0].split(" ").map(Number);

console.log(
  lines.slice(1) //1行目以降を配列に
    .filter(line =>　//x以上を残す 
      line.split(",").map(Number)[k - 1] >= x//sのk列目の値>=x
    )
    .join("\n")//改行区切り
);
```