起因
现在ACM用得多的基本上就两种语言,C++和Python3,还有部分Java,但是当年ACM必学的Pascal、新近流行的rust也有人用,只不过用户很少。
就以一道codeforce上的算法小题为样本,来对比一样用户数量、执行效率、易写程度。
题目
https://codeforces.com/contest/1997/problem/C
样本总量:20150
用户数量对比
C++20:7800
C++17:9150
C++11:1550
Python3:1050
Python2:1
Haskell:2
C:45
C#:17
Go:14
Java21:450
Java8:180
Kotlin:9
Pascal(FPC):3
Rust:30
各语言数量差异很大,很直观。基本上是C++统治的时代了。
语言代码量对比
就取各语言中代码量最少的一个
C++20
#include<bits/stdc++.h>
using namespace std;
int t,n,ans;
string st;
int main(){cin>>t;while(t--){cin>>n>>st;ans=n/2;for(int i=0;i<n;i++)if(st[i]=='(')ans+=2;cout<<ans<<endl;}return 0;
}
C
#include <stdio.h>char s[200100];
int main(void){int tt, ii;int ans;int n, i;scanf("%d", &tt);for (ii=1; ii<=tt; ii++){scanf("%d", &n);ans=n/2;scanf("%s", s+1);for (i=1; i<=n; i++){if (s[i]=='('){ans+=2; }}printf("%d\n", ans);}return 0;
}
C++14
#include<bits/stdc++.h>
using namespace std;
int main(){string st;int t,n,ans;cin>>t;while(t--){cin>>n>>st;ans=n/2;for(int i=0;i<n;i++)if(st[i]=='(')ans+=2;cout<<ans<<endl;}return 0;
}
Python3
for _ in[0]*int(input()):print((y:=int(input()))//2+2*input().count('('))
Pascal
Vart,i,n,dem1:Longint;kq:Int64;a:Array[0..300000] of Longint;
Procedure giai;
Var i:Longint;s:ansistring;
BeginReadln(n);Readln(s);{d1:=0;d2:=0;For i:=1 to length(s) do if i mod 2=0 thenIf s[i]='(' then inc(d1) else inc(d2); Inc(d1);}dem1:=1;a[dem1]:=1;kq:=0;For i:=2 to length(s) doIf s[i]=')' thenBeginkq:=kq+i-a[dem1];Dec(dem1);EndElse if s[i]='(' thenBeginInc(dem1);a[dem1]:=i;EndElse if dem1>0 thenBeginkq:=kq+i-a[dem1];Dec(dem1);EndElseBeginInc(dem1);a[dem1]:=i;End;Writeln(kq);
End;
BEGIN// Assign(input,'contest168c.inp');Reset(input);// Assign(output,'contest168c.out');Rewrite(output);Readln(t);For i:=1 to t do giai();
END.
Rust
rust">use std::io::*;fn main() {let s = read_to_string(stdin()).unwrap();let mut it = s.lines();let mut nx = || it.next().unwrap();let t: usize = nx().parse().unwrap();for _ in 0..t {let _: usize = nx().parse().unwrap();let s = nx().chars();let mut sum = 0;let mut st = vec![];for (i,ch) in s.enumerate() {if ch == '_' {if st.is_empty() {st.push(i);} else {sum += i - st.pop().unwrap();}} else if ch == '(' {st.push(i);} else {sum += i - st.pop().unwrap();}}println!("{sum}");}
}
Java
java">import java.util.*;public class RanitMukherjee {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int t = sc.nextInt();while(t-- > 0) {int n = sc.nextInt();char[] arr = sc.next().toCharArray();int count = 0;for(int i = 1; i < n; i+=2) {if(arr[i] == '(') count += 3;else count++;}System.out.println(count);}sc.close();}
}
Haskell
import qualified Data.ByteString.Char8 as C
import Data.MaybeconstOpen :: Char
constOpen = '('constClose :: Char
constClose = ')'constBlank :: Char
constBlank = '_'parseInt :: C.ByteString -> Int
parseInt x = fst (fromJust (C.readInt x))getInts :: IO [Int]
getInts = doline <- C.getLinelet res = map (parseInt) (C.words line)return resparseStr :: C.ByteString -> String
parseStr x = C.unpack xgetStrs :: IO [String]
getStrs = doline <- C.getLinelet res = map (parseStr) (C.words line)return resfill :: String -> String
fill [x] = [x]
fill (x : y : rest)| (y == constBlank && x == constOpen) = x : constClose : fill rest| (y == constBlank && x == constClose) = x : constOpen : fill rest| otherwise = fill (y : rest)getBracketPairs :: [(Char, Int)] -> [Int] -> [(Int, Int)]
getBracketPairs [] _ = []
getBracketPairs ((c, i) : rest) stack| (c == constOpen) = getBracketPairs rest (i : stack)| otherwise = (i, head stack) : getBracketPairs rest (tail stack)ans :: IO ()
ans = do[n] <- getInts[s] <- getStrslet sFill = constOpen : fill (tail s)let pairs = zip sFill [1 .. ]let bracketPairs = getBracketPairs pairs []let dists = map (\(x, y) -> x - y) bracketPairslet res = sum distsprint resreturn ()main :: IO ()
main = do[t] <- getIntssequence (replicate t ans)return ()
Kotlin
import java.util.LinkedListfun main() {repeat(readln().toInt()) {val n = readln().toInt()val s = readln()var ans = 0Lval bracketPositions = LinkedList<Int>()for (i in s.indices) {var c = s[i]if (c == '_') {c = if (bracketPositions.isEmpty()) '(' else ')'}if (c == ')') {ans += i - bracketPositions.pollLast()}elsebracketPositions.addLast(i)}println(ans)}
}
C#
using System.Text;namespace EvenPositions;
class Program
{private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024 * 10), Encoding.ASCII, false, 1024 * 10);private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024 * 10), Encoding.ASCII, 1024 * 10);private static void Main(string[] args){int t = int.Parse(reader.ReadLine());for (int i = 0; i < t; i++){writer.WriteLine(Solve());}writer.Flush();}private static int Solve(){reader.ReadLine();string s = reader.ReadLine();int ans = 0;for (int i = 1; i < s.Length; i += 2){if (s[i] == ')') ans += 1;else ans += 3;}return ans;}
}
总结
一个语言用户数量的多少,最相关的还是难易程度,同样的代码写起来越简单肯定越受人喜欢;其次就是运行效率,尽管简单,过不了运行测试也不行;再就是用户基数,用的人多,学习资料才多,而用户基数就是前面两点确定的。