这是用一个键选择分支的 switch。 按一个字符选择:C・C++・Java・C#・JS・TS switch (k) { case 'U': … }(JS・TS 用字符串 "U"),Python 3.10+ match k: case "U":,Craykon 选择 (k) { 情况 "U": … 跳出; }。 把做同样事情的情况合在一起(比如十个数字):C・C++・JS・TS・C#(仅限空 case)case '0': case '1': …,Java 箭头 case '+', '-' ->,Python case "+" | "-":,Craykon 情况 "0", "1", …:。 陷阱 ① 贯穿:C・C++・JS・TS 和 Java 旧式 case: 语句在缺少 break 时会接着执行下一个 case。 U 后面忘了 break 就会连 D 一起执行,频道又回到原处。 C# 把它当作编译错误,Java 箭头 switch、Python match、Craykon 选择 都不会贯穿。 Craykon 的 跳出 只跳出选择。 ② 在 1 号按 D:(ch - 2) % c + 1 在 C・C++・Java・C#・JS・TS・Craykon 中因为 % 保留负号而得到 0 号。 要用 (ch - 2 + c) % c + 1 或 Java Math.floorMod(Python 的 % 总是不小于 0)。 ③ 嵌套条件的顺序:要在 switch 之前先问“是否关着”,关机时音量和频道才不会变。 ④ 所有非数字键都先处理攒下的数字(不只是 #)。 所以 5U 是 5 号的下一个 6 号。 ⑤ 转到相同频道时不覆盖上一个频道。 ⑥ +・- 会取消静音。
Pythonmain.py · 60 行
c = int(input())keys = input().strip()power = Falsech, vol, muted = 1, 10, Falseprev = 0 # 바로 전 채널(0이면 아직 없음)buf = "" # 누른 숫자를 모아 둔 것out = []def go(to): """채널을 to로 바꾼다. 지금과 같으면 바꾼 것이 아니다.""" global ch, prev if to != ch: prev, ch = ch, todef commit(): global buf if buf: v = int(buf) # "007"은 7 buf = "" if 1 <= v <= c: go(v)for k in keys: if not power: # 꺼져 있으면 P와 ? 말고는 듣지 않는다 if k == "P": power = True elif k == "?": out.append("OFF") continue if k.isdigit(): buf += k if len(buf) == 3: commit() continue commit() # 숫자가 아닌 키는 모아 둔 숫자부터 처리한다 match k: case "#": pass case "P": power = False case "U": go(ch % c + 1) case "D": go((ch - 2) % c + 1) # Python의 %는 늘 0 이상이라 1번 → c번 case "B": if prev: go(prev) case "+" | "-": vol = min(30, vol + 1) if k == "+" else max(0, vol - 1) muted = False case "M": muted = not muted case "?": out.append(f"CH {ch} MUTE" if muted else f"CH {ch} VOL {vol}")print("\n".join(out))
JavaScriptmain.js · 62 行
const [cLine, keysLine] = require("fs").readFileSync(0, "utf8").split("\n");const c = Number(cLine);const keys = keysLine.trim();let power = false;let ch = 1, vol = 10, muted = false;let prev = 0; // 바로 전 채널(0이면 아직 없음)let buf = ""; // 누른 숫자를 모아 둔 것const out = [];const go = (to) => { if (to !== ch) [prev, ch] = [ch, to]; // 지금과 같으면 바꾼 것이 아니다};const commit = () => { if (buf === "") return; const v = Number(buf); // "007"은 7 buf = ""; if (v >= 1 && v <= c) go(v);};for (const k of keys) { if (!power) { // 꺼져 있으면 P와 ? 말고는 듣지 않는다 if (k === "P") power = true; else if (k === "?") out.push("OFF"); continue; } if (k >= "0" && k <= "9") { buf += k; if (buf.length === 3) commit(); continue; } commit(); // 숫자가 아닌 키는 모아 둔 숫자부터 처리한다 switch (k) { case "#": break; case "P": power = false; break; case "U": go((ch % c) + 1); break; case "D": go(((ch - 2 + c) % c) + 1); // JS의 %는 음수를 남기니 c를 더해 둔다 break; case "B": if (prev !== 0) go(prev); break; case "+": case "-": // 두 경우가 같은 일을 하도록 일부러 이어 내려간다 vol = k === "+" ? Math.min(30, vol + 1) : Math.max(0, vol - 1); muted = false; break; case "M": muted = !muted; break; case "?": out.push(muted ? `CH ${ch} MUTE` : `CH ${ch} VOL ${vol}`); break; }}console.log(out.join("\n"));
TypeScriptmain.ts · 64 行
import { readFileSync } from "node:fs";const [cLine, keysLine]: string[] = readFileSync(0, "utf8").split("\n");const c = Number(cLine);const keys = keysLine.trim();let power = false;let ch = 1, vol = 10, muted = false;let prev = 0; // 바로 전 채널(0이면 아직 없음)let buf = ""; // 누른 숫자를 모아 둔 것const out: string[] = [];const go = (to: number): void => { if (to !== ch) [prev, ch] = [ch, to]; // 지금과 같으면 바꾼 것이 아니다};const commit = (): void => { if (buf === "") return; const v = Number(buf); // "007"은 7 buf = ""; if (v >= 1 && v <= c) go(v);};for (const k of keys) { if (!power) { // 꺼져 있으면 P와 ? 말고는 듣지 않는다 if (k === "P") power = true; else if (k === "?") out.push("OFF"); continue; } if (k >= "0" && k <= "9") { buf += k; if (buf.length === 3) commit(); continue; } commit(); // 숫자가 아닌 키는 모아 둔 숫자부터 처리한다 switch (k) { case "#": break; case "P": power = false; break; case "U": go((ch % c) + 1); break; case "D": go(((ch - 2 + c) % c) + 1); // JS의 %는 음수를 남기니 c를 더해 둔다 break; case "B": if (prev !== 0) go(prev); break; case "+": case "-": // 두 경우가 같은 일을 하도록 일부러 이어 내려간다 vol = k === "+" ? Math.min(30, vol + 1) : Math.max(0, vol - 1); muted = false; break; case "M": muted = !muted; break; case "?": out.push(muted ? `CH ${ch} MUTE` : `CH ${ch} VOL ${vol}`); break; }}console.log(out.join("\n"));
JavaMain.java · 62 行
import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.IOException;public class Main { static int c, ch = 1, vol = 10, prev = 0; static boolean muted = false; static StringBuilder buf = new StringBuilder(); // 누른 숫자를 모아 둔 것 // 채널을 to로 바꾼다. 지금과 같으면 바꾼 것이 아니다 static void go(int to) { if (to != ch) { prev = ch; ch = to; } } static void commit() { if (buf.length() == 0) return; int v = Integer.parseInt(buf.toString()); // "007"은 7 buf.setLength(0); if (v >= 1 && v <= c) go(v); } public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); c = Integer.parseInt(in.readLine().trim()); String keys = in.readLine().trim(); boolean power = false; StringBuilder out = new StringBuilder(); for (char k : keys.toCharArray()) { if (!power) { // 꺼져 있으면 P와 ? 말고는 듣지 않는다 if (k == 'P') power = true; else if (k == '?') out.append("OFF\n"); continue; } if (Character.isDigit(k)) { buf.append(k); if (buf.length() == 3) commit(); continue; } commit(); // 숫자가 아닌 키는 모아 둔 숫자부터 처리한다 // 화살표 switch는 이어 내려가지 않아 break가 필요 없다 switch (k) { case '#' -> { } case 'P' -> power = false; case 'U' -> go(ch % c + 1); case 'D' -> go(Math.floorMod(ch - 2, c) + 1); // floorMod는 늘 0 이상 case 'B' -> { if (prev != 0) go(prev); } case '+', '-' -> { vol = k == '+' ? Math.min(30, vol + 1) : Math.max(0, vol - 1); muted = false; } case 'M' -> muted = !muted; case '?' -> out.append("CH ").append(ch).append(muted ? " MUTE" : " VOL " + vol).append('\n'); default -> { } } } System.out.print(out); }}
C#Main.cs · 82 行
using System;using System.Text;class Program{ static int c, ch = 1, vol = 10, prev = 0; static bool muted = false; static string buf = ""; // 누른 숫자를 모아 둔 것 // 채널을 to로 바꾼다. 지금과 같으면 바꾼 것이 아니다 static void Go(int to) { if (to != ch) { prev = ch; ch = to; } } static void Commit() { if (buf == "") return; int v = int.Parse(buf); // "007"은 7 buf = ""; if (v >= 1 && v <= c) Go(v); } static void Main() { c = int.Parse(Console.ReadLine().Trim()); string keys = Console.ReadLine().Trim(); bool power = false; var sb = new StringBuilder(); foreach (char k in keys) { if (!power) { // 꺼져 있으면 P와 ? 말고는 듣지 않는다 if (k == 'P') power = true; else if (k == '?') sb.Append("OFF\n"); continue; } if (char.IsDigit(k)) { buf += k; if (buf.Length == 3) Commit(); continue; } Commit(); // 숫자가 아닌 키는 모아 둔 숫자부터 처리한다 // C#은 case 끝에 break가 없으면 컴파일 오류라서 이어 내려가는 실수가 없다 switch (k) { case '#': break; case 'P': power = false; break; case 'U': Go(ch % c + 1); break; case 'D': Go((ch - 2 + c) % c + 1); // C#의 %는 음수를 남기니 c를 더해 둔다 break; case 'B': if (prev != 0) Go(prev); break; case '+': case '-': // 빈 case는 다음 case와 묶을 수 있다 vol = k == '+' ? Math.Min(30, vol + 1) : Math.Max(0, vol - 1); muted = false; break; case 'M': muted = !muted; break; case '?': sb.Append(muted ? $"CH {ch} MUTE\n" : $"CH {ch} VOL {vol}\n"); break; } } Console.Write(sb); }}
C++main.cpp · 73 行
#include <algorithm>#include <iostream>#include <string>int c, ch = 1, vol = 10, prev = 0;bool muted = false;std::string buf; // 누른 숫자를 모아 둔 것// 채널을 to로 바꾼다. 지금과 같으면 바꾼 것이 아니다void go(int to) { if (to != ch) { prev = ch; ch = to; }}void commit() { if (buf.empty()) return; int v = std::stoi(buf); // "007"은 7 buf.clear(); if (v >= 1 && v <= c) go(v);}int main() { std::string keys, out; std::cin >> c >> keys; bool power = false; for (char k : keys) { if (!power) { // 꺼져 있으면 P와 ? 말고는 듣지 않는다 if (k == 'P') power = true; else if (k == '?') out += "OFF\n"; continue; } if (k >= '0' && k <= '9') { buf += k; if (buf.size() == 3) commit(); continue; } commit(); // 숫자가 아닌 키는 모아 둔 숫자부터 처리한다 switch (k) { case '#': break; case 'P': power = false; break; case 'U': go(ch % c + 1); break; case 'D': go((ch - 2 + c) % c + 1); // C++의 %는 음수를 남기니 c를 더해 둔다 break; case 'B': if (prev) go(prev); break; case '+': vol = std::min(30, vol + 1); muted = false; break; case '-': vol = std::max(0, vol - 1); muted = false; break; case 'M': muted = !muted; break; case '?': out += "CH " + std::to_string(ch) + (muted ? " MUTE" : " VOL " + std::to_string(vol)) + "\n"; break; } } std::cout << out;}
Cmain.c · 81 行
#include <stdio.h>#include <stdlib.h>static int c, ch = 1, vol = 10, muted = 0, prev = 0;static char buf[4];static int blen = 0;/* 채널을 to로 바꾼다. 지금과 같으면 바꾼 것이 아니다 */static void go(int to) { if (to != ch) { prev = ch; ch = to; }}static void commit(void) { if (blen == 0) return; buf[blen] = '\0'; int v = atoi(buf); /* "007"은 7 */ blen = 0; if (v >= 1 && v <= c) go(v);}static char keys[10002];int main(void) { int power = 0; scanf("%d %10001s", &c, keys); for (char *p = keys; *p; p++) { char k = *p; if (!power) { /* 꺼져 있으면 P와 ? 말고는 듣지 않는다 */ if (k == 'P') power = 1; else if (k == '?') puts("OFF"); continue; } switch (k) { /* 숫자 열 개는 case를 잇대어 써서 한 곳으로 모은다(일부러 이어 내려감) */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': buf[blen++] = k; if (blen == 3) commit(); continue; /* 아래의 commit을 건너뛰고 다음 키로 */ default: break; } commit(); /* 숫자가 아닌 키는 모아 둔 숫자부터 처리한다 */ switch (k) { case '#': break; case 'P': power = 0; break; case 'U': go(ch % c + 1); break; case 'D': go((ch - 2 + c) % c + 1); /* C의 %는 음수를 남기니 c를 더해 둔다 */ break; case 'B': if (prev) go(prev); break; case '+': vol = vol < 30 ? vol + 1 : 30; muted = 0; break; case '-': vol = vol > 0 ? vol - 1 : 0; muted = 0; break; case 'M': muted = !muted; break; case '?': if (muted) printf("CH %d MUTE\n", ch); else printf("CH %d VOL %d\n", ch, vol); break; } } return 0;}
Craykonmain.cray · 111 行
c = 控制台.读行().转数字();keys = 控制台.读行().去空白();power = 假;ch = 1;vol = 10;muted = 假;prev = 0; // 바로 전 채널(0이면 아직 없음)buf = ""; // 누른 숫자를 모아 둔 것// 채널을 to로 바꾼다. 지금과 같으면 바꾼 것이 아니다가기(to){ 如果 (to != ch) { prev = ch; ch = to; }}모은숫자처리(){ 如果 (buf != "") { v = buf.转数字(); // "007"은 7 buf = ""; 如果 (v >= 1 && v <= c) { 가기(v); } }}循环 (i = 0; i < keys.长度; i++){ k = keys[i]; 如果 (!power) { // 꺼져 있으면 P와 ? 말고는 듣지 않는다 如果 (k == "P") { power = 真; } 否则 如果 (k == "?") { 控制台.输出("OFF"); } 继续; } 选择 (k) { 情况 "0": 情况 "1": 情况 "2": 情况 "3": 情况 "4": 情况 "5": 情况 "6": 情况 "7": 情况 "8": 情况 "9": buf = buf + k; 如果 (buf.长度 == 3) { 모은숫자처리(); } 跳出; 默认: 모은숫자처리(); // 숫자가 아닌 키는 모아 둔 숫자부터 처리한다 选择 (k) { 情况 "P": power = 假; 跳出; 情况 "U": 가기(ch % c + 1); 跳出; 情况 "D": 가기((ch - 2 + c) % c + 1); // %는 음수를 남기니 c를 더해 둔다 跳出; 情况 "B": 如果 (prev != 0) { 가기(prev); } 跳出; 情况 "+": vol = 数学.较小值(30, vol + 1); muted = 假; 跳出; 情况 "-": vol = 数学.较大值(0, vol - 1); muted = 假; 跳出; 情况 "M": muted = !muted; 跳出; 情况 "?": 如果 (muted) { 控制台.输出("CH " + ch + " MUTE"); } 否则 { 控制台.输出("CH " + ch + " VOL " + vol); } 跳出; } 跳出; }}