The longest consecutive values in a vector and the position at which it starts and ends

I have a large matrix where I want to find the value that has been repeated the most. Then define its starting and ending indexes. For example
Thanks for the help in advanse!
A = [35, 25, 40, 20, 20, 30, 30, 30, 30, 30, 9, 20, 30, 10, 30]
The solution should be as below
The_Answer = 30
Starting_index = 6;
Ending_index = 10

2 件のコメント

Geoff Hayes
Geoff Hayes 2021 年 10 月 13 日
@Yaser Khojah - is this homework? What have you tried so far? What are the dimensions of the large matrix?
Yaser Khojah
Yaser Khojah 2021 年 10 月 13 日
It is a large project, however, I have the code in a different computer which I do not have an access to it. I have tried using diff.

サインインしてコメントする。

 採用された回答

One approach —
A = [35, 25, 40, 20, 20, 30, 30, 30, 30, 30, 9, 20, 30, 10, 30];
[Au,~,ix] = unique(A, 'stable');
Tally = accumarray(ix,1);
HiFreq = Au(Tally==max(Tally));
Lv = false(size(A));
Lv(A==HiFreq) = true;
Start = strfind(Lv, [0 1])+1;
End = [strfind(Lv,[1 0]) numel(A)];
Len = End - Start;
[~,Idx] = max(Len);
Desired_Answer = HiFreq
Desired_Answer = 30
Desired_Start = Start(Idx)
Desired_Start = 6
Desired_End = End(Idx)
Desired_End = 10
.

8 件のコメント

Yaser Khojah
Yaser Khojah 2021 年 10 月 13 日
Thanks so much, I will try it and get back to you soon :)
Star Strider
Star Strider 2021 年 10 月 13 日
My pleasure!
.
My original code would fail to detect a string of ‘30’ (or whatever the most frequent number is) at the beginning of the vector. This revision corrects for that —
A = [30, 30, 30, 30, 30, 30, 30, 30, 35, 25, 40, 20, 20, 30, 30, 30, 30, 30, 9, 20, 30, 10, 30]; % Test
A = [35, 25, 40, 20, 20, 30, 30, 30, 30, 30, 9, 20, 30, 10, 30]; % Original
[Au,~,ix] = unique(A, 'stable');
Tally = accumarray(ix,1);
HiFreq = Au(Tally==max(Tally));
Lv = false(size(A));
Lv(A==HiFreq) = true;
Lv = [false Lv];
Start = strfind(Lv, [0 1]);
End = [strfind(Lv,[1 0]) numel(A)]-1;
Len = End - Start;
[~,Idx] = max(Len);
Desired_Answer = HiFreq
Desired_Answer = 30
Desired_Start = Start(Idx)
Desired_Start = 6
Desired_End = End(Idx)
Desired_End = 10
This revision of my code is more robust, and the result is the same.
.
Yaser Khojah
Yaser Khojah 2021 年 10 月 14 日
Excellent and thank you so much for helping me. It is working :)
Yaser Khojah
Yaser Khojah 2021 年 10 月 14 日
編集済み: Yaser Khojah 2021 年 10 月 14 日
I have issue with some cases as below. Would you please help me with them.
1) Case 1:
A = [9 9 8 9 8 8 8 7 2 1];
In this case the answer should be 8 as it is continous.
Desired_Answer= 8;
Desired_End = 7;
2) Case 2:
A = [9 9 8 8 8 7 2 9 3];
In this case the answer should be 8 as it is continous.
Desired_Answer = 8;
Desired_End = 5;
3) Case 3:
A = [9 9 9 8 8 8 7 2 9 3];
In this case the answer should be 9 as it is continous and the largest
Desired_Answer = 9;
Desired_End = 3;
4) Case 4:
A = [9 8 7 6 8 7 2 9 3];
In this case there is no asnwer.
Desired_Answer = no value
Thanks so much!
As always, my pleasure!
Case 3’ is straightforward, using a slight revision of my revised code (in my Comment) —
A = [9 9 9 8 8 8 7 2 9 3];
[Au,~,ix] = unique(A, 'stable');
Tally = accumarray(ix,1);
HiFreq = Au(Tally==max(Tally));
Lv = false(size(A));
Lv(A==HiFreq) = true;
Lv = [false Lv];
Start = strfind(Lv, [0 1]);
End = unique([strfind(Lv,[1 0]) numel(A)]-1);
Len = End - Start;
[~,Idx] = max(Len);
Desired_Answer = HiFreq
Desired_Answer = 9
Desired_Start = Start(Idx)
Desired_Start = 1
Desired_End = End(Idx)
Desired_End = 3
Adding the unique call eliminates the last element of ‘End’ if it is duplicated.
My code was not designed to deal with the others, since they were not part of the original problem, or the problem description (at least as I understood it). I will work on this later.
.
Yaser Khojah
Yaser Khojah 2021 年 10 月 14 日
Thanks so much. Take your time and hopefully it will work :)
This appears to work correctly for all of them, and with only minor changes in my original code.
To test it, un-comment (remove the ‘%’) from the ‘A’ vector to test , then run the code. (Keep the ‘%’ for the others not being tested. I included my original ‘Test’ vector as well in the ‘A Library’ of test vectors. The fprintf call allowed me to keep track of the loop iterations easily. I’m leaving it in, although commented so it won’t execute.)
A = [35, 25, 40, 20, 20, 30, 30, 30, 30, 30, 9, 20, 30, 10, 30];
% A = [30, 30, 30, 30, 30, 30, 30, 30, 35, 25, 40, 20, 20, 30, 30, 30, 30, 30, 9, 20, 30, 10, 30]; % Test
% A = [9 9 8 9 8 8 8 7 2 1];
% A = [9 9 8 8 8 7 2 9 3];
% A = [9 9 9 8 8 8 7 2 9 3];
% A = [9 8 7 6 8 7 2 9 3];
[Au,~,ix] = unique(A, 'stable');
Tally = accumarray(ix,1);
HiFreq = Au(Tally==max(Tally));
% Lv = false(size(A));
for k = 1:numel(HiFreq)
Element = HiFreq(k);
Lv = false(size(A));
Lv(A==HiFreq(k)) = true;
Lv = [false Lv];
Start = strfind(Lv, [0 1]);
End = unique([strfind(Lv,[1 0]) numel(A)]-1);
minidx = min(numel(Start),numel(End));
EndStt = [End(1:minidx); Start(1:minidx)];
Len = End(1:minidx) - Start(1:minidx);
[~,Idx(k)] = max(Len);
EndStart(:,k) = EndStt(:,Idx(k));
% fprintf('-------------------------\n')
end
HiFreqv = [];
Startv = [];
Endv = [];
Check = -diff(EndStart);
if all(Check)
[~,IxES] = max(-diff(EndStart));
HiFreqv = HiFreq(IxES);
Startv = EndStart(2,IxES);
Endv = EndStart(1,IxES);
end
Desired_Answer = HiFreqv
Desired_Answer = 30
Desired_Start = Startv
Desired_Start = 6
Desired_End = Endv
Desired_End = 10
Definitely an interesting problem!
.

サインインしてコメントする。

その他の回答 (2 件)

Matt J
Matt J 2021 年 10 月 13 日
編集済み: Matt J 2021 年 10 月 13 日
Using "Tools for Processing Consecutive Repetitions in Vectors",
A = [35, 25, 40, 20, 20, 30, 30, 30, 30, 30, 9, 20, 30, 10, 30];
[starts,stops,lengths]=groupLims(groupConsec(A),1);
[~,i]=max(lengths);
The_Answer = A(starts(i))
The_Answer = 30
Starting_index = starts(i)
Starting_index = 6
Ending_index = stops(i)
Ending_index = 10

3 件のコメント

Yaser Khojah
Yaser Khojah 2021 年 10 月 14 日
編集済み: Yaser Khojah 2021 年 10 月 14 日
Thanks so much Mat for your help.
Matt J
Matt J 2021 年 10 月 14 日
Really? It doesn't look like anyone has downloaded it recently.
Yaser Khojah
Yaser Khojah 2021 年 10 月 14 日
I want to use it but I cant dowload this code in my project machine.

サインインしてコメントする。

Image Analyst
Image Analyst 2021 年 10 月 14 日
If you have the Image Processing Toolbox (like most people do), you can use bwareafilt() to extract the longest run. Then the code becomes simply:
A = [35, 25, 40, 20, 20, 30, 30, 30, 30, 30, 9, 20, 30, 10, 30]
da = bwareafilt([0, diff(A)] == 0, 1)
startingIndex = max([1, find(da, 1, 'first')-1])
endingIndex = find(da, 1, 'last')
You see
A =
35 25 40 20 20 30 30 30 30 30 9 20 30 10 30
da =
1×15 logical array
0 0 0 0 0 0 1 1 1 1 0 0 0 0 0
startingIndex =
6
endingIndex =
10

カテゴリ

ヘルプ センター および File ExchangePlatform and License についてさらに検索

タグ

質問済み:

2021 年 10 月 13 日

回答済み:

2021 年 10 月 14 日

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by