---
# System prepended metadata

title: 問題文（多重ループとポインタ）

---

# 問題文（多重ループとポインタ）

## 問題
入力として、1行目に数列L1の大きさ、2行目にint型の数列L1、3行目に数列L2の大きさ、4行目にint型の数列L2が与えられる。

L1の大きさ（1行目の値）がL2の大きさ（2行目の値）以上のとき、L1の中にL2がいくつ含まれているか出力せよ。また、L2の大きさがL1の大きさよりも大きいとき、L2の中にL1がいくつ含まれているか出力せよ。
ただし、数列内の値を参照するときはポインタを使うこと。

### 入力
入力は以下の形式で標準入力から与えられる。
```
a
L1
b
L2
```
### 出力
問題の指示に従って出力せよ。

#### 入力1
```
4
1 0 2 3
2
2 3
```
#### 出力1
```
1
```
#### 入力2
```
3
2 1 2
10
3 2 1 2 3 1 2 1 2 3
```
#### 出力2
```
2
```
#### 入力3
```
4
0 1 1 1
2
1 1
```
#### 出力3
```
2
```
# 解答
```
#include <stdio.h>
int main(void) {
  int a;                  //数列L1の大きさを入れる変数
  scanf("%d", &a);        //数列L1の大きさを読み取る
  int L1[a];                //数列L1の値を入れる変数
  for (int i = 0; i < a; i++) {
    scanf("%d", &L1[i]);  //数列L1の値を読み取る
  }

  int b;                  //数列L2の大きさを入れる変数
  scanf("%d", &b);        //数列L2の大きさを読み取る
  int L2[b];                //数列L2の値を入れる変数
  for (int i = 0; i < b; i++) {
    scanf("%d", &L2[i]);  //数列L2の値を読み取る
  }
  
  int lva, sva;           //a,bのうち、大きい方をlva, 小さい方をsvaに代入する
  int *pl, *ps;           //L1,L2のうち、大きい方をpl, 小さい方をpsに代入する
  
  if(b <= a){
    /*L1の方がL2以上のとき*/
    pl = L1;
    ps = L2;
    lva = a;
    sva = b;
  }else{
    /*L2の方が大きい時*/
    pl = L2;
    ps = L1;  
    lva = b;
    sva = a;
  }
  
  int ans = 0;            //含まれていた回数を代入する変数

  for (int i = 0; i < lva-sva+1; i++) {
    /*plを1字ずつ進める. lva-sva+1以降は,plの残りの字数がsva字よりすくなくなるため必要ない*/
    for (int j = 0; j < sva; j++) {
    　/*psを1字ずつ進める*/
      if (*(pl+i+j) != *(ps+j)) {
        break;            //現在指しているplとpsの値が違うときjのfor文を終了し,iのfor文に戻る
      }
      if (j == sva-1) {
        /*現在指しているplの値とpsの値が最後まで同じ*/
        ans += 1;
      }
    }
  }

  printf("%d\n", ans);      //ansの出力

  return 0;
}
```

# 解説
### 【細分化】
![](https://i.imgur.com/ReXKPur.png)


### 【注意】
1. 数列L1, L2の大きさは1以上50未満である
2. L1の大きさ（1行目の値）とL2の大きさ（2行目の値）の大小関係によって処理が異なる
3. 数列内の値を参照するときは、ポインタを使わなくてはならない

### 【手順】
#### １．キーボードから入力を読み込む
- 数列L1の大きさを読み込むint型変数aを宣言
  - 数列L1の大きさをscanfで読み取る
- 領域の大きさaの数列L1を読み込むint型配列L1を宣言
  - for文でa回繰り返しscanfを行い、L1の値を読み取る
- 数列L2の大きさを読み込むint型変数bを宣言
  - 数列L2の大きさをscanfで読み取る
- 領域の大きさbの数列L2を読み込むint型配列L2を宣言
  - for文でb回繰り返しscanfを行い、L2の値を読み取る

#### ２．a, bを適切な変数に代入する・L1, L2を適切なポインタに渡す
- int型変数lva, svaを宣言する
- ポインタ変数pl, psを宣言する
- 適切な変数に値を渡す
  - (b<=a)のときの処理
    - plにL1を渡す
    - psにL2を渡す
    - lvaにaの値を渡す
    - svaにbの値を渡す
  - (b<=a)以外のときの処理
    - plにL2を渡す
    - psにL1を渡す
    - lvaにbの値を渡す
    - svaにaの値を渡す

#### ３．plの中にpsがいくつ含まれているか出力する
- 含まれていた数を渡すint型変数ansを宣言する
- plを0字目からlva-sva字目までfor文で繰り返す
- 上記のfor文の中（二重for文）で、psを0字目からsva字目までfor文で繰り返す
   - 現在参照しているplとpsの値が一致していないとき
     - 内側のfor文を終了する
   - 現在参照しているplとpsの値が一致しているとき
     - 内側のfor文を続ける
     - psの最後の文字まで一致したとき、ansを1増やす
- ansを出力する




