删除所有相同的值
第一行给出个数 n,第二行给出 n 个整数,第三行给出整数 x。
从列表中删除所有等于 x 的值。
第一行输出剩下的个数,第二行按原顺序输出剩下的数,用一个空格隔开。
如果什么都不剩,第一行输出 0,第二行留空。
如果 x 不在列表中,列表保持不变。
- 输入
- 1 ≤ n ≤ 10,000,所有数和 x 都是 -1,000 到 1,000 之间的整数
- 输出
- 两行:剩下的个数,剩下的数(没有则为空行)
8 2 2 1 2 2 2 3 2 2
2 1 3
3 4 4 4 4
0
第一行给出个数 n,第二行给出 n 个整数,第三行给出整数 x。
从列表中删除所有等于 x 的值。
第一行输出剩下的个数,第二行按原顺序输出剩下的数,用一个空格隔开。
如果什么都不剩,第一行输出 0,第二行留空。
如果 x 不在列表中,列表保持不变。
8 2 2 1 2 2 2 3 2 2
2 1 3
3 4 4 4 4
0
运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。
$ 就绪
请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。
最常见的陷阱是一边从前往后遍历一边删除。
删掉一个元素后,后面的会往前挪一格,但下标仍然加一,所以连续的 "2 2" 中第二个 2 会被跳过。
Python 的 for v in a: a.remove(v) 也因同样的原因跳过。
两种改法:把要留下的收集到新列表(Python [v for v in a if v != x],JavaScript、TypeScript a.filter(v => v !== x)),或者从后往前删。
一次删光的工具:Java list.removeIf(v -> v == x),C# list.RemoveAll(v => v == x),C++20 std::erase(a, x)(之前用 erase-remove 惯用法),C 用一个写入下标把留下的往前挪。
还有两个陷阱:JavaScript 的 a.splice(a.indexOf(x), 1) 只删一个,而 x 不存在时 indexOf 为 -1,会删掉最后一个元素。
给 Java List<Integer> 的 remove(x) 传 int,删的不是值而是第 x 个位置(按值删要写 remove(Integer.valueOf(x)))。
Craykon 解法从后往前用 a.按位置移除(i) 删除(a.移除(x) 只删一个)。
n = int(input())a = list(map(int, input().split()))x = int(input())rest = [v for v in a if v != x]print(len(rest))print(*rest)const [n, ...rest] = require("fs").readFileSync(0, "utf8").trim().split(/\s+/).map(Number);const a = rest.slice(0, n);const x = rest[n];const left = a.filter((v) => v !== x);console.log(left.length + "\n" + left.join(" "));import { readFileSync } from "node:fs";const [n, ...rest]: number[] = readFileSync(0, "utf8").trim().split(/\s+/).map(Number);const a: number[] = rest.slice(0, n);const x: number = rest[n];const left: number[] = a.filter((v) => v !== x);console.log(left.length + "\n" + left.join(" "));import java.util.ArrayList;import java.util.List;import java.util.Scanner;import java.util.StringJoiner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); List<Integer> a = new ArrayList<>(); for (int i = 0; i < n; i++) a.add(sc.nextInt()); int x = sc.nextInt(); a.removeIf(v -> v == x); StringJoiner out = new StringJoiner(" "); for (int v : a) out.add(String.valueOf(v)); System.out.println(a.size()); System.out.println(out); }}using System;using System.Collections.Generic;using System.Linq; class Program{ static void Main() { Console.ReadLine(); List<int> a = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList(); int x = int.Parse(Console.ReadLine()); a.RemoveAll(v => v == x); Console.WriteLine(a.Count); Console.WriteLine(string.Join(" ", a)); }}#include <iostream>#include <vector> int main() { int n, x; std::cin >> n; std::vector<int> a(n); for (int& v : a) std::cin >> v; std::cin >> x; std::erase(a, x); // C++20. 그 전에는 a.erase(std::remove(a.begin(), a.end(), x), a.end()); std::cout << a.size() << "\n"; for (size_t i = 0; i < a.size(); i++) std::cout << (i ? " " : "") << a[i]; std::cout << "\n";}#include <stdio.h> int main(void) { static int a[10000]; int n, x, m = 0; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); scanf("%d", &x); /* 남길 것만 앞으로 당겨 쓴다: m은 다음에 쓸 자리 */ for (int i = 0; i < n; i++) if (a[i] != x) a[m++] = a[i]; printf("%d\n", m); for (int i = 0; i < m; i++) printf(i ? " %d" : "%d", a[i]); putchar('\n'); return 0;}n = 控制台.读行().转数字();a = 控制台.读数字();x = 控制台.读行().转数字();// 뒤에서부터 지우면 지운 뒤 당겨지는 칸을 건너뛰지 않는다循环 (i = a.数量 - 1; i >= 0; i--){ 如果 (a[i] == x) { a.按位置移除(i); }}控制台.输出(a.数量);控制台.输出(a);