Reputation: 300
I have a list and I need to find and extract all numbers in close proximity to a new list.
for example I have a list:
1,5,10,8,11,14,15,11,14,1,4,7,5,9
so if I want to extract all numbers that are close by 3(only 3, the gap must be 3, so 11,14 is correct, 11,13 is not.) near each other how can I design this without hard-coding the whole thing?
the result should look like: 8,11,14,11,14,1,4,7
This doesn't look too hard ,but I'm kind stuck, all I can come up with is a loop that checks n+1 member of the loop if it's more than n by 3 and include the n+1 member in a new list, however I don't know how to include the n member without making it appear on the new list twice if there is a string of needed numbers.
any ideas?
Upvotes: 3
Views: 165
Reputation: 23955
And a Haskell version:
f g xs = dropWhile (null . drop 1) $ foldr comb [[last xs]] (init xs) where
comb a bbs@(b:bs)
| abs (a - head b) == g = (a:head bbs) : bs
| otherwise =
if null (drop 1 b) then [a] : bs else [a] : bbs
Output:
*Main> f 3 [5,10,8,11,14,15,11,14,1,4,7,5,9]
[[8,11,14],[11,14],[1,4,7]]
*Main> f 5 [5,10,8,11,14,15,11,14,1,4,7,5,9]
[[5,10]]
Upvotes: 0
Reputation: 363577
Just loop through the list, checking the next and previous element, and save the current one if it differs by 3 from either one. In Python, that's
>>> l = [1,5,10,8,11,14,15,11,14,1,4,7,5,9]
>>> # pad with infinities to ease the final loop
>>> l = [float('-inf')] + l + [float('inf')]
>>> [x for i, x in enumerate(l[1:-1], 1)
... if 3 in (abs(x - l[i-1]), abs(x - l[i+1]))]
[8, 11, 14, 11, 14, 1, 4, 7]
Upvotes: 2
Reputation: 4565
A simple C++ code below:
assuming ar
is the array of the initial integers and mark is a boolean array
for(int i=1;i<N;i++){
if(ar[i]-ar[i-1]==3){
mark[i]=1;
mark[i-1]=1;
}
}
Now to print the interesting numbers,
for(int i=0;i<N;i++){
if(mark[i]==1)cout<<ar[i]<<" ";
}
The idea behind the implementation is, we mark a number as interesting if the difference from it to its previous one is 3 or if the difference between it and its next number is 3.
Upvotes: 1
Reputation: 78316
In Matlab
list = [1,5,10,8,11,14,15,11,14,1,4,7,5,9]
then
list(or([diff([0 diff(list)==3]) 0],[0 diff(list)==3]))
returns
8 11 14 11 14 1 4 7
For those who don't understand Matlab diff(list)
returns the first (forward) differences of the elements in list
. The expression [0 diff(list)]
pads the first differences with a leading 0
to make the result the same length as the original list
. The rest should be obvious.
In a nutshell: take forward differences and backward differences, select the elements where either difference is 3
.
Upvotes: 1
Reputation: 11577
that's a single loop:
public List<int> CloseByN(int n, List<int> oldL)
{
bool first = true;
int last = 0;
bool isLstAdded = false;
List<int> newL = new List<int>();
foreach(int curr in oldL)
{
if(first)
{
first = false;
last = curr;
continue;
}
if(curr - last == n)
{
if(isLstAdded == false)
{
newL.Add(last);
isLstAdded = true;
}
newL.Add(curr);
}
else
{
isLstAdded = false;
}
last = curr;
}
return newL;
}
tested on your input and got your output
Upvotes: 0