使用开关计算字符频率

问题描述 投票:0回答:3

我试图计算每个字符在字符串中出现的时间,我使用开关和 for 循环,但是,它们没有正确增加。这是我的代码

let countChar x = 
  match x with
    'A' -> countA := !countA + 1;
  | 'C' -> countC := !countC + 1;
  | 'T' -> countT := !countT + 1;
  | 'G' -> countG := !countG + 1;   
;;

let demoStri = "ACGTACGT" in 
for j = 0 to 7 do
  countChar demoStri.[j];
  let tempA = !countA in
  print_int tempA;
  print_string "\n";
  let tempC = !countC in
  print_int tempC;
  print_string "\n";
  let tempG = !countG in
  print_int tempG;
  print_string "\n";
  let tempT = !countT in 
  print_int tempT;
  print_string "\n";
done

但由于某种原因,它只递增 1,并且返回 1 0 0 0、2 0 0 0、3 0 0 0 等等......我想知道这个过程中是否出了问题?

pattern-matching ocaml increment ref
3个回答
0
投票

我认为这段代码当前的形式没有问题,它对我有用。您没有显示

countA
countC
countT
countG
的初始化,但如果我按如下方式初始化:

let countA = ref 0
let countC = ref 0
let countT = ref 0
let countG = ref 0

然后运行你的代码,我得到这一系列数字(将四个折叠成一行以节省空间):

1 0 0 0
1 1 0 0
1 1 1 0
1 1 1 1
2 1 1 1
2 2 1 1
2 2 2 1
2 2 2 2

0
投票

这里最大的问题是您使用

tempH
变量来索引字符串,而不是您应该使用的
j

let () = 
    let demoStri = "ACGTACGT" in 
    let countA = ref 0 in
    let countC = ref 0 in
    let countT = ref 0 in
    let countG = ref 0 in
    for j = 0 to String.length demoStri - 1 do
        match demoStri.[j] with
        | 'A'-> countA := !countA +1
        | 'C'-> countC := !countC +1
        | 'T'-> countT := !countT +1
        | 'G'-> countG := !countG +1
        | _ -> assert false
    done;
    print_int !countA; print_string "\n";
    print_int !countC; print_string "\n";
    print_int !countT; print_string "\n";
    print_int !countG; print_string "\n"

0
投票

解决这个问题完全没有必要对现有答案、命令式特性和可变状态进行补充。您可以折叠字符串,在每次迭代时更新记录。结果将是每个字符的计数。

# type count = {a: int; c: int; t: int; g: int};;
type count = { a : int; c : int; t : int; g : int; }
# let print_int_endline = Format.printf "%d\n";;
val print_int_endline : int -> unit = <fun>
# let {a; c; t; g} =
    String.fold_left
      (fun ({a;c;t;g} as r) ->
         function
         | 'A' -> {r with a=a+1}
         | 'C' -> {r with c=c+1}
         | 'T' -> {r with t=t+1}
         | 'G' -> {r with g=g+1}
         |  _  -> r)
      {a=0; c=0; t=0; g=0}
      "ACGTACGT"
  in
  print_int_endline a;
  print_int_endline c;
  print_int_endline t;
  print_int_endline g;;
2
2
2
2
- : unit = ()
© www.soinside.com 2019 - 2024. All rights reserved.