MATLAB 仅运行 switch-case 块中的第一个 case

MATLAB only runs first case in a switch-case block

我正在尝试将 csv 文件中的数据分成数据“块”,然后将这些数据分为 10 个不同的类别。每个块的顶部都有一组空格。每个类别包含 660 个块。目前,我的代码成功地放入了第一个块,但只是第一个块。它确实正确地计算了块的数量。我不明白为什么它只在块计数正常工作时才放入第一个块,我们将不胜感激。 可以从此处下载 csv 文件。 https://archive.ics.uci.edu/ml/machine-learning-databases/00195/

    fid = fopen('Train_Arabic_Digit.txt','rt');
traindata = textscan(fid, '%f%f%f%f%f%f%f%f%f%f%f%f%f', 'MultipleDelimsAsOne',true, 'Delimiter','[;', 'HeaderLines',1);
fclose(fid);
% Each line in Train_Arabic_Digit.txt or Test_Arabic_Digit.txt represents 
% 13 MFCCs coefficients in the increasing order separated by spaces. This 
% corresponds to one analysis frame. Lines are organized into blocks, which
% are a set of 4-93 lines separated by blank lines and corresponds to a 
% single speech utterance of an spoken Arabic digit with 4-93 frames.
% Each spoken digit is a set of consecutive blocks.
% TO DO: how get blocks...split? with /n?
% In Train_Arabic_Digit.txt there are 660 blocks for each spoken digit. The
% first 330 blocks represent male speakers and the second 330 blocks 
% represent the female speakers. Blocks 1-660 represent the spoken digit 
% "0" (10 utterances of /0/ from 66 speakers), blocks 661-1320 represent
% the spoken digit "1" (10 utterances of /1/ from the same 66 speakers 
% 33 males and 33 females), and so on up to digit 9.
 content = fileread( 'Train_Arabic_Digit.txt' ) ;
  default = regexp(content,'\n','split');
  digit0=[];
  digit1=[];
  digit2=[];
  digit3=[];
  digit4=[];
  digit5=[];
  digit6=[];
  digit7=[];
  digit8=[];
  digit9=[];
  blockcount=0;
  a=0;
  for i=1:1:length(default)
      if strcmp(default{i},'            ')
          blockcount=blockcount+1;
      else
          switch blockcount % currently only works for blockcount=1 even though
              %it does pick up the number of blocks...
              case blockcount>0 && blockcount<=660 %why does it not recognize 2 as being<660
                  a=a+1;
                  digit0=[digit0 newline default{i}];
              case blockcount>660 && blockcount<=1320
                  digit1=[digit1 newline default{i}];
              case blockcount<=1980 && blockcount>1320
                  digit2=[digit2 newline default{i}];
              case blockcount<=2640 && blockcount>1980
                  digit3=[digit3 newline default{i}];
              case blockcount<=3300 && blockcount>2640
                  digit4=[digit4 newline default{i}];
              case blockcount<=3960 && blockcount>3300
                  digit5=[digit5 newline default{i}];
              case blockcount<=4620 && blockcount>3960
                  digit6=[digit6 newline default{i}];
              case blockcount<=5280 && blockcount>4620
                  digit7=[digit7 newline default{i}];
              case blockcount<=5940 && blockcount>5280
                  digit8=[digit8 newline default{i}];
              case blockcount<=6600 && blockcount>5940
                  digit9=[digit9 newline default{i}];
          end
      end
  end

那是因为您以某种方式混淆了 if-else 语法和 switch-case。请注意,像 blockcount>0 && blockcount<=660 这样的表达式总是 returns 一个逻辑值,这意味着它要么是 0 要么是 1。现在,当 blockcount 等于 1 时,第一个 case 表达式的结果也是 1,其余的结果0,所以,1==1 并且第一个块运行。但是当 blockcount 变为 2 时,第一个 case 表达式的结果仍然是 1 和 2~=1 所以什么也没有发生!

您可以使用 if-else 或将您的 case 表达式更改为包含值范围的元胞数组。根据文档:

The switch block tests each case until one of the case expressions is true. A case is true when:

  • For numbers, case_expression == switch_expression.

  • For character vectors, strcmp(case_expression,switch_expression) == 1.

  • For objects that support the eq function, case_expression == switch_expression. The output of the overloaded eq function must be either a logical value or convertible to a logical value.

  • For a cell array case_expression, at least one of the elements of the cell array matches switch_expression, as defined above for numbers, character vectors, and objects.

应该是这样的:

switch blockcount
  case num2cell(0:660)
    digit0 ...
  case num2cell(661:1320)
    digit1 ...
  ...
end

BUT,此代码块将永远完成。首先,始终避免在循环中使用 a = [a b]。调整矩阵的大小非常耗时。始终 preallocate a 并执行 a(i) = b.