# 解題紀錄
## 題目:a182. 字串操作
## 📙 題目描述
1. 兩兩交換:將字串內相鄰兩個字元交換,例如字串 "apcsntnu" 先分組成 (ap)(cs)(nt)(nu),將會交換為 (pa)(sc)(tn)(un),即得到 "pasctnun"。
2. 兩兩排序:將字串內相鄰兩個字元按照字典序排序,字元的字典序為 a < b < ... < z,例如字串 "family" 先分組成 (fa)(mi)(ly),將會交換成 (af)(im)(ly),即得到 "afimly"。
3. 完美重排:假設字串長度為
,將字串內的字元編號為 $0,1,2...,n - 1$
,將字串分成兩半為 $0, 1, \cdots, \frac{n}{2}-1$
和 $\frac{n}{2}, \frac{n}{2} + 1, \cdots, n-1$
,並且組合成 $0, \frac{n}{2}, 1, \frac{n}{2} + 1, \cdots, \frac{n}{2}-1, n-1$
。例如 "apcsntnu" 拆成 "apcs" 和 "ntnu",然後交錯成 "anptcnsu"。
給定 $k$ 個操作,請依序操作字串,輸出最後的字串結果。
**範例:**
輸入說明
第一行輸入一個字串 𝑆(2≤|𝑆|≤100),字串長度保證為偶數。接下來一行輸入一個正整數 𝑘,接下來有 𝑘 行,每一行有一個數字,種類為 0,1,2。
(60 分): |𝑆|≤10, 𝑘=1 且保證操作為完美重排
(40 分): 無限制
輸出說明
輸出操作完之後的字串內容。
```txt
範例輸入 #1 範例輸出 #1
apcsntnu anptcnsu
1
2
```
```txt
範例輸入 #2 範例輸出 #2
facebook bocfkoae
4
2
0
2
1
```
---
## ✒️ 解題思路
有不同的操作模式,因此使用自訂函式對每個操作進行模擬
---
## 💻 C 語言解法
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 交換相鄰的字元
void op0(char* s) {
int len = strlen(s);
for (int i = 0; i < len; i += 2) { // 每次跳過兩個字元
s[i] ^= s[i + 1] ^= s[i] ^= s[i + 1];
}
}
// 對字元進行排序(相鄰兩個字元交換)
void op1(char* s) {
int len = strlen(s);
for (int i = 0; i < len; i += 2) {
if (s[i] > s[i + 1]) {
s[i] ^= s[i + 1] ^= s[i] ^= s[i + 1];
}
}
}
char* op2(char* s) {
int len = strlen(s);
char* ns = malloc(len + 1);
for (int i = 0,j = 0; i < len / 2; i++) {
ns[j++] = s[i];
ns[j++] = s[len / 2 + i];
}
ns[len] = '\0'; // 確保字串結尾
free(s); // 釋放原有記憶體
return ns;
}
int main(void) {
int n;
char buffer[101];
scanf("%100s", buffer); // 限制輸入最大長度為 100
char* s = malloc(strlen(buffer) + 1);
strcpy(s, buffer);
scanf("%d", &n); // 輸入操作次數
for (int i = 0; i < n; i++) {
int op;
scanf("%d", &op);
switch (op) {
case 0:
op0(s);
break;
case 1:
op1(s);
break;
case 2:
s = op2(s);
break;
}
}
puts(s); // 輸出結果
free(s); // 釋放記憶體
return 0;
}
```