So I have written this quick sort function, and it works for SOME input.
For example it works for the following inputs : "5 4 3 2 1", "3 4 5 6 7", etc.
However when I input something like : "0 3 5 4 -5 100 7777 2014" it will always mix up the multi digit numbers.
I was hoping someone could help point me to where my code is failing at this test case.
Sort.cpp
std::vector<int> QuickSort::sortFunc(std::vector<int> vec, int left, int right) {
int i = left, j = right;
int tmp;
int pivot = vec.at( (left + right) / 2 );
/* partition */
while (i <= j) {
while (vec.at(i) < pivot)
i++;
while (vec.at(j) > pivot)
j--;
if (i <= j) {
tmp = vec.at(i);
vec.at(i) = vec.at(j);
vec.at(j) = tmp;
i++;
j--;
}
}
/* recursion */
if (left < j)
return sortFunc( vec, left, j );
if (i < right)
return sortFunc( vec, i, right );
else
{
return vec;
}
}
main.cpp
int main()
{
// The user inputs a string of numbers (e.g. "6 4 -2 88 ..etc") and those integers are then put into a vector named 'vec'.
std::vector<int> vec;
// Converts string from input into integer values, and then pushes said values into vector.
std::string line;
if ( getline(std::cin, line) )
{
std::istringstream str(line);
int value;
str >> value;
vec.push_back( value );
while ( str >> value )
{
vec.push_back( value );
}
}
// Creating QuickSort object.
QuickSort qSort;
QuickSort *ptrQSort = &qSort;
// Creating new vector that has been 'Quick Sorted'.
int vecSize = vec.size();
std::vector<int> qSortedVec;
qSortedVec = ptrQSort->sortFunc( vec, 0, vecSize-1 );
// Middle, start, and end positions on the vector.
int mid = ( 0 + (vec.size()-1) ) / 2;
int start = 0, end = vec.size() - 1;
// Creating RecursiveBinarySearch object.
RecursiveBinarySearch bSearch;
RecursiveBinarySearch *ptrBSearch = &bSearch;
//bool bS = ptrBSearch->binarySearch( qSortedVec, mid, start, end );
bool bS = ptrBSearch->binarySearch( bSortedVec, mid, start, end );
/*--------------------------------------OUTPUT-----------------------------------------------------------------------*/
// Print out inputted integers and the binary search result.
// Depending on the binary search, print either 'true' or 'false'.
if ( bS == 1 )
{
std::cout << "true ";
}
if ( bS == 0 )
{
std::cout << "false ";
}
// Prints the result of the 'quick sorted' array.
int sortedSize = qSortedVec.size();
for ( int i = 0; i < sortedSize; i++ )
{
std::cout << qSortedVec[i] << " ";
}
std::cout << "\n";
return 0;
}
Thanks for any and all help you can give me guys.
I'm not sure if this solves it completely, but after sorting the left part, you still need to sort the right part, but you already return instead.
Also, passing the vector by value and returning it is overhead and not needed, because in the end there should only be one version of the vector, so passing by reference is preferred. Passing by value and returning is sometimes needed when doing recursion, especially when backtracking (looking for different paths), but not in this case where left and right provide the needed state.
Related
If your sequence is 4 2 1, the largest jump is from 4 to 2. If your sequence is 3 10 5 16 8 4 2 1, the largest jump is from 5 to 16.
I've made an algorithm however I'm not completely sure what I have done wrong (whever I haven't made the loop properly, set my variables correctly, or something else). I'm not sure what I need to set my index, BiggestDiff, or CurrentDiff too. I tried using a while loop to compare each number in my vector but I get zero (I'm assuming because I set BiggestDiff to zero)
If anyone can point me in the right direction, show me an example, or something else, that will be greatly appreciated.
Here is my code below
int findBiggestDiff(std::vector<int> sequence)
{
int index = 0;
int BiggestDiff = 0 ;
int CurrentDiff = BiggestDiff;
CurrentDiff = std::abs(sequence[index] - sequence[index + 1]);
while (index < sequence.size())
{
if (CurrentDiff > BiggestDiff)
{
BiggestDiff = CurrentDiff;
}
return index;
}
}
Try this:
{
int indexOfBiggestJump = 0;
int BiggestDiff = 0 ;
int CurrentDiff = BiggestDiff;
for(int i = 0; i < sequence.size() - 1; i++) {
CurrentDiff = std::abs(sequence[i] - sequence[i + 1]);
if (CurrentDiff > BiggestDiff)
{
BiggestDiff = CurrentDiff;
indexOfBiggestJump = i;
}
}
return indexOfBiggestJump;
}
There are several errors in your code.
your return index literally does nothing, only returns index (which will be 0) always.
you are not saving the index of the biggest jump anywhere.
if you are looking positions i and i + 1, you must go until sequence.size() - 1, otherwise you will look out of the bounds of sequence.
You aren't recalculating CurrentDiff at all. Also, your return statement in the in the wrong spot. You can do something like this (not tested)
int findLargest( const std::vector<int> &sequence ) {
if ( sequence.size() < 2 ) return -1; // if there's not at least two elements, there's nothing valid.
int index = 0;
int biggestIndex = -1;
int biggestDiff = -1;
while (index < sequence.size() - 1) // -1 so that the +1 below doesn't go out of range
{
// get the current difference
int currentDiff = std::abs(sequence[index] - sequence[index + 1]);
if (currentDiff > biggestDiff)
{
// update stats
biggestIndex = index;
biggestDiff = currentDiff;
}
++index;
}
return biggestIndex
}
int main() {
//…
int index = findLargest( sequence );
if ( index != -1 ) {
std::cout << "Biggest difference was between " << sequence[index] << " and " << sequence[index+1];
}
}
I want to know if this backtracking algorithm actually works.
In the text book Foundations of Algorithms, 5th edition, it is defined as follows:
Algorithm 5.4: The Backtracking Algorithm for the Sum-of-Subsets Problem
Problem: Given n positive integers (weights) and a positive integer W,
determine all combinations of the integers that sum up to W.
Inputs: positvie integer n, sorted (nondecreasing order) array of
positive integers w indexed from 1 to n, and a positive integer
W.
Outputs: all combinations of the integers that sum to W.
void sum_of_subsets(index i,
int weight, int total) {
if (promising(i))
if (weight == W)
cout << include[1] through include [i];
else {
include[i + 1] = "yes"; // Include w[i + 1].
sum_of_subsets(i + 1, weight + w[i + 1], total - w[i + 1]);
include[i + 1] = "no"; // Do not include w[i + 1].
sum_of_subsets(i + 1, weight, total - w[i + 1]);
}
}
bool promising (index i); {
return (weight + total >= W) && (weight == W || weight + w[i + 1] <= W);
}
Following our usual convention, n, w, W, and include are not
inputs to our routines. If these variables were defined globally, the
top-level call to sum_of_subsets would be as follows:
sum_of_subsets(0, 0, total);
At the end of chapter 5, exercise 13 asks:
Use the Backtracking algorithm for the Sum-of-Subsets problem (Algorithm 5.4)
to find all combinations of the following numbers that sum to W = 52:
w1 = 2 w2 = 10 w3 = 13 w4 = 17 w5 = 22 w6 = 42
I've implemented this exact algorithm, accounting for arrays that start at 1 and it just does not work...
void sos(int i, int weight, int total) {
int yes = 1;
int no = 0;
if (promising(i, weight, total)) {
if (weight == W) {
for (int j = 0; j < arraySize; j++) {
std::cout << include[j] << " ";
}
std::cout << "\n";
}
else if(i < arraySize) {
include[i+1] = yes;
sos(i + 1, weight + w[i+1], total - w[i+1]);
include[i+1] = no;
sos(i + 1, weight, total - w[i+1]);
}
}
}
int promising(int i, int weight, int total) {
return (weight + total >= W) && (weight == W || weight + w[i+1] <= W);
}
I believe the problem is here:
sos(i + 1, weight, total - w[i+1]);
sum_of_subsets(i+1, weight, total-w[i+1]);
When you reach this line you are not backtracking correctly.
Is anyone able to identify a problem with this algorithm or actually code it to work?
I personally find the algorithm problematic. There is no bounds checking, it uses a lot of globals, and it assumes an array is indexed from 1. I don't think you can copy it verbatim. It's pseudocode for the actual implementation. In C++ arrays always start from 0. So you're likely to have problems when you try do include[i+1] and you are only checking i < arraySize.
The algorithm also assumes you have a global variable called total, which is used by the function promising.
I have reworked the code a bit, putting it inside a class, and simplified it somewhat:
class Solution
{
private:
vector<int> w;
vector<int> include;
public:
Solution(vector<int> weights) : w(std::move(weights)),
include(w.size(), 0) {}
void sos(int i, int weight, int total) {
int yes = 1;
int no = 0;
int arraySize = include.size();
if (weight == total) {
for (int j = 0; j < arraySize; j++) {
if (include[j]) {
std::cout << w[j] << " ";
}
}
std::cout << "\n";
}
else if (i < arraySize)
{
include[i] = yes;
//Include this weight
sos(i + 1, weight + w[i], total);
include[i] = no;
//Exclude this weight
sos(i + 1, weight, total);
}
}
};
int main()
{
Solution solution({ 2, 10, 13, 17, 22, 42 });
solution.sos(0, 0, 52);
//prints: 10 42
// 13 17 22
}
So yes, as others pointed out, you stumbled over the 1 based array index.
That aside, I think you should ask the author for a partial return of the money you paid for the book, because the logic of his code is overly complicated.
One good way not to run into bounds problems is to not use C++ (expecting hail of downvotes for this lol).
There are only 3 cases to test for:
The candidate value is greater than what is remaining. (busted)
The candidate value is exactly what is remaining.
The candidate value is less than what is remaining.
The promising function tries to express that and then the result of that function is re-tested again in the main function sos.
But it could look as simple as this:
search :: [Int] -> Int -> [Int] -> [[Int]]
search (x1:xs) t path
| x1 > t = []
| x1 == t = [x1 : path]
| x1 < t = search xs (t-x1) (x1 : path) ++ search xs t path
search [] 0 path = [path]
search [] _ _ = []
items = [2, 10, 13, 17, 22, 42] :: [Int]
target = 52 :: Int
search items target []
-- [[42,10],[22,17,13]]
Now, it is by no means impossible to achieve a similar safety net while writing C++ code. But it takes determination and a conscious decision on what you are willing to cope with and what not. And you need to be willing to type a few more lines to accomplish what the 10 lines of Haskell do.
First off, I was bothered by all the complexity of indexing and range checking in the original C++ code. If we look at our Haskell code (which works with lists),
it is confirmed that we do not need random access at all. We only ever look at the start of the remaining items. And we append a value to the path (in Haskell we append to the front because speed) and eventually we append a found combination to the result set. With that in mind, bothering with indices is kind of over the top.
Secondly, I rather like the way the search function looks - showing the 3 crucial tests without any noise surrounding them. My C++ version should strive to be as pretty.
Also, global variables are so 1980 - we won't have that. And tucking those "globals" into a class to hide them a bit is so 1995. We won't have that either.
And here it is! The "safer" C++ implementation. And prettier... um... well some of you might disagree ;)
#include <cstdint>
#include <vector>
#include <iostream>
using Items_t = std::vector<int32_t>;
using Result_t = std::vector<Items_t>;
// The C++ way of saying: deriving(Show)
template <class T>
std::ostream& operator <<(std::ostream& os, const std::vector<T>& value)
{
bool first = true;
os << "[";
for( const auto item : value)
{
if(first)
{
os << item;
first = false;
}
else
{
os << "," << item;
}
}
os << "]";
return os;
}
// So we can do easy switch statement instead of chain of ifs.
enum class Comp : int8_t
{ LT = -1
, EQ = 0
, GT = 1
};
static inline
auto compI32( int32_t left, int32_t right ) -> Comp
{
if(left == right) return Comp::EQ;
if(left < right) return Comp::LT;
return Comp::GT;
}
// So we can avoid index insanity and out of bounds problems.
template <class T>
struct VecRange
{
using Iter_t = typename std::vector<T>::const_iterator;
Iter_t current;
Iter_t end;
VecRange(const std::vector<T>& v)
: current{v.cbegin()}
, end{v.cend()}
{}
VecRange(Iter_t cur, Iter_t fin)
: current{cur}
, end{fin}
{}
static bool exhausted (const VecRange<T>&);
static VecRange<T> next(const VecRange<T>&);
};
template <class T>
bool VecRange<T>::exhausted(const VecRange<T>& range)
{
return range.current == range.end;
}
template <class T>
VecRange<T> VecRange<T>::next(const VecRange<T>& range)
{
if(range.current != range.end)
return VecRange<T>( range.current + 1, range.end );
return range;
}
using ItemsRange = VecRange<Items_t::value_type>;
static void search( const ItemsRange items, int32_t target, Items_t path, Result_t& result)
{
if(ItemsRange::exhausted(items))
{
if(0 == target)
{
result.push_back(path);
}
return;
}
switch(compI32(*items.current,target))
{
case Comp::GT:
return;
case Comp::EQ:
{
path.push_back(*items.current);
result.push_back(path);
}
return;
case Comp::LT:
{
auto path1 = path; // hope this makes a real copy...
path1.push_back(*items.current);
search(ItemsRange::next(items), target - *items.current, path1, result);
search(ItemsRange::next(items), target, path, result);
}
return;
}
}
int main(int argc, const char* argv[])
{
Items_t items{ 2, 10, 13, 17, 22, 42 };
Result_t result;
int32_t target = 52;
std::cout << "Input: " << items << std::endl;
std::cout << "Target: " << target << std::endl;
search(ItemsRange{items}, target, Items_t{}, result);
std::cout << "Output: " << result << std::endl;
return 0;
}
The code implements the algorithm correctly, except that you did not apply the one-based array logic in your output loop. Change:
for (int j = 0; j < arraySize; j++) {
std::cout << include[j] << " ";
}
to:
for (int j = 0; j < arraySize; j++) {
std::cout << include[j+1] << " ";
}
Depending on how you organised your code, make sure that promising is defined when sos is defined.
See it run on repl.it. Output:
0 1 0 0 0 1
0 0 1 1 1 0
The algorithm works fine: the second and third argument to the sos function act as a window in which the running sum should stay, and the promising function verifies against this window. Any value outside this window will be either to small (even if all remaining values were added to it, it will still be less than the target value), or too great (already overrunning the target). These two constraints are explained in the beginning of chapter 5.4 in the book.
At each index there are two possible choices: either include the value in the sum, or don't. The value at includes[i+1] represents this choice, and both are attempted. When there is a match deep down such recursing attempt, all these choices (0 or 1) will be output. Otherwise they are just ignored and switched to the opposite choice in a second attempt.
FYI: I am new to programming.
I have an arraysize of 10 and the sentinel value is 0.
My original array is [1 2 3] ( user input) but my reverse is [0 0 0 0 0 0 0 3 2 1].
I need help to make my reverse array [3 2 1].
Here is my code:
int temp;
for (int i = 0; i < arraysize/2; i++)
{
temp = array[arraysize-1-i];
array[arraysize - i - 1] = array[i];
array[i] = temp;
}
cout << "The reverse array: ";
for (int i = 0; i < arraysize; i++)
cout << array[i]<< ' ';
cout << endl;
Just use the standard library algorithms
auto end = std::find(std::begin(array),std::end(array),0);
std::reverse(std::begin(array),end);
//And if you only want to print the non-zero values:
size_t effectiveArraySize = end - std::begin(array);
If the fixed size array is not part of your requirement, you should put your user data in a vector that automaticaly grows as large as you need, instead of using an array that might turn out to be too small:
std::vector<int> v;
while(true) {
int t;
cin >> t;
if (t == 0) {
break;
}
v.push_back(t);
}
std::reverse(v.begin(),v.end());
That way, you don't have any sentinel values in your array / vector to begin with.
Note: Using the respective functions from the STL (std::reverse and std::find) is better, I was just guessing that you are bound to implement this on your own.
Step one: Write a proper reverse function. One that takes (a pointer to) the beginning as well as (a pointer to) the end of the range that should be reversed.
Step two: Write a function to find (the first position of) your sentinel in an array (given via beginning and end, again)
Step three: Connect the two: Reverse from the beginning to the position of your sentinel.
Example without templates:
void reverse(int * from, int * to) {
while ((to - from) > 1) {
--to;
int temp = *from;
*from = *to;
*to = temp;
++from;
}
}
int const * find(int const * from,
int const * const to,
int const value) {
while ((from != to) && (*from != value)) {
++from;
}
return from;
}
void reverse_until (int * const from,
int * const to,
int const sentinel) {
int const * const position_sentinel = find(from, to, sentinel);
reverse(from, from + (position_sentinel - from));
// return the sentinel position from this function
// if you want only the reversed part
}
Tested with:
int main() {
int test[10];
for (size_t i = 0; i < 10; ++i) {
test [i] = i + 1;
}
reverse_until (test, test + 10, 6);
copy(test, test + 10, ostream_iterator<int>{cout, " "});
return 0;
}
(live here)
You need to find the actual length of the array, before performing the reverse operation, and then use that length for all further operations.
Like this:
int actualArraySize = 0;
while(actualArraySize < arraysize && array[actualArraySize]!=0)
{
actualArraySize++;
}
int temp;
for (int i = 0; i < actualArraySize/2; i++)
{
temp = array[actualArraySize-1-i];
array[actualArraySize - i - 1] = array[i];
array[i] = temp;
}
cout << "The reverse array: ";
for (int i = 0; i < actualArraySize; i++)
cout << array[i]<< ' ';
cout << endl;
Note that, actualArraySize can be less than or equal to arraysize, but, not more than it, because of the condition in while(actualArraySize < arraysize && array[actualArraySize]!=0), which means that stop when either a 0 is found or the size of the array is reached.
I have done a test in C++ asking for a function that returns one of the indices that splits the input vector in 2 parts having the same sum of the elements, for eg: for the vec = {1, 2, 3, 5, 4, -1, 1, 1, 2, -1}, it may return 3, because 1+2+3 = 6 = 4-1+1+1+2-1. So I have done the function that returns the correct answer:
int func(const std::vector< int >& vecIn)
{
for (std::size_t p = 0; p < vecin.size(); p++)
{
if (std::accumulator(vecIn.begin(), vecIn.begin() + p, 0) ==
std::accumulator(vecIn.begin() + p + 1, vecIn.end(), 0))
return p;
}
return -1;
}
My problem was when the input was a very long vector containing just 1 (or -1), the return of the function was slow. So I have thought of starting the search for the wanted index from middle, and then go left and right. But the best approach I suppose is the one where the index is in the merge-sort algorithm order, that means: n/2, n/4, 3n/4, n/8, 3n/8, 5n/8, 7n/8... where n is the size of the vector. Is there a way to write this order in a formula, so I can apply it in my function?
Thanks
EDIT
After some comments I have to mention that I had done the test a few days ago, so I have forgot to put and mention the part of no solution: it should return -1... I have updated also the question title.
Specifically for this problem, I would use the following algorithm:
Compute the total sum of the vector. This gives two sums (empty vector, and full vector)
for each element in order, move one element from full to empty, which means adding the value of next element from sum(full) to sum(empty). When the two sums are equal, you have found your index.
This give a o(n) algorithm instead of o(n2)
You can solve the problem much faster without calling std::accumulator at each step:
int func(const std::vector< int >& vecIn)
{
int s1 = 0;
int s2 = std::accumulator(vecIn.begin(), vecIn.end(), 0);
for (std::size_t p = 0; p < vecin.size(); p++)
{
if (s1 == s2)
return p;
s1 += vecIn[p];
s2 -= vecIn[p];
}
}
This is O(n). At each step, s1 will contain the sum of the first p elements, and s2 the sum of the rest. You can update both of them with an addition and a subtraction when moving to the next element.
Since std::accumulator needs to iterate over the range you give it, your algorithm was O(n^2), which is why it was so slow for many elements.
To answer the actual question: Your sequence n/2, n/4, 3n/5, n/8, 3n/8 can be rewritten as
1*n/2
1*n/4 3*n/4
1*n/8 3*n/8 5*n/8 7*n/8
...
that is to say, the denominator runs from i=2 up in powers of 2, and the nominator runs from j=1 to i-1 in steps of 2. However, this is not what you need for your actual problem, because the example you give has n=10. Clearly you don't want n/4 there - your indices have to be integer.
The best solution here is to recurse. Given a range [b,e], pick a value middle (b+e/2) and set the new ranges to [b, (b+e/2)-1] and [(b+e/2)=1, e]. Of course, specialize ranges with length 1 or 2.
Considering MSalters comments, I'm afraid another solution would be better. If you want to use less memory, maybe the selected answer is good enough, but to find the possibly multiple solutions you could use the following code:
static const int arr[] = {5,-10,10,-10,10,1,1,1,1,1};
std::vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );
// compute cumulative sum
std::vector<int> cumulative_sum( vec.size() );
cumulative_sum[0] = vec[0];
for ( size_t i = 1; i < vec.size(); i++ )
{ cumulative_sum[i] = cumulative_sum[i-1] + vec[i]; }
const int complete_sum = cumulative_sum.back();
// find multiple solutions, if there are any
const int complete_sum_half = complete_sum / 2; // suggesting this is valid...
std::vector<int>::iterator it = cumulative_sum.begin();
std::vector<int> mid_indices;
do {
it = std::find( it, cumulative_sum.end(), complete_sum_half );
if ( it != cumulative_sum.end() )
{ mid_indices.push_back( it - cumulative_sum.begin() ); ++it; }
} while( it != cumulative_sum.end() );
for ( size_t i = 0; i < mid_indices.size(); i++ )
{ std::cout << mid_indices[i] << std::endl; }
std::cout << "Split behind these indices to obtain two equal halfs." << std::endl;
This way, you get all the possible solutions. If there is no solution to split the vector in two equal halfs, mid_indices will be left empty.
Again, you have to sum up each value only once.
My proposal is this:
static const int arr[] = {1,2,3,5,4,-1,1,1,2,-1};
std::vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );
int idx1(0), idx2(vec.size()-1);
int sum1(0), sum2(0);
int idxMid = -1;
do {
// fast access without using the index each time.
const int& val1 = vec[idx1];
const int& val2 = vec[idx2];
// Precompute the next (possible) sum values.
const int nSum1 = sum1 + val1;
const int nSum2 = sum2 + val2;
// move the index considering the balanace between the
// left and right sum.
if ( sum1 - nSum2 < sum2 - nSum1 )
{ sum1 = nSum1; idx1++; }
else
{ sum2 = nSum2; idx2--; }
if ( idx1 >= idx2 ){ idxMid = idx2; }
} while( idxMid < 0 && idx2 >= 0 && idx1 < vec.size() );
std::cout << idxMid << std::endl;
It does add every value only once no matter how many values. Such that it's complexity is only O(n) and not O(n^2).
The code simply runs from left and right simultanuously and moves the indices further if it's side is lower than the other.
You want nth term of the series you mentioned. Then it would be:
numerator: (n - 2^((int)(log2 n)) ) *2 + 1
denominator: 2^((int)(log2 n) + 1)
I came across the same question in Codility tests. There is a similar looking answer above (didn't pass some of the unit tests), but below code segment was successful in tests.
#include <vector>
#include <numeric>
#include <iostream>
using namespace std;
// Returns -1 if equilibrium point is not found
// use long long to support bigger ranges
int FindEquilibriumPoint(vector<long> &values) {
long long lower = 0;
long long upper = std::accumulate(values.begin(), values.end(), 0);
for (std::size_t i = 0; i < values.size(); i++) {
upper -= values[i];
if (lower == upper) {
return i;
}
lower += values[i];
}
return -1;
}
int main() {
vector<long> v = {-1, 3, -4, 5, 1, -6, 2, 1};
cout << "Equilibrium Point:" << FindEquilibriumPoint(v) << endl;
return 0;
}
Output
Equilibrium Point:1
Here it is the algorithm in Javascript:
function equi(arr){
var N = arr.length;
if (N == 0){ return -1};
var suma = 0;
for (var i=0; i<N; i++){
suma += arr[i];
}
var suma_iz = 0;
for(i=0; i<N; i++){
var suma_de = suma - suma_iz - arr[i];
if (suma_iz == suma_de){
return i};
suma_iz += arr[i];
}
return -1;
}
As you see this code satisfy the condition of O(n)
I'm getting the longest consecutive increasing numbers in an array with 10 items
int list[] = {2,3,8,9,10,11,12,2,6,8};
int start_pos = 0;
int lenght=0; // lenght of the sub-~consetuve
for (int a =0; a <=9; a++ )
{
if ((list[a]+1) == (list[a+1])) {
// continue just the string;
lenght++;
} else {
start_pos = a;
}
}
cout << lenght << " and start in " << start_pos;
getchar();
but it not working, it should return in length & start_pos ( 3 and lenght 4 ) because longest increasing is from 9 , 10 , 11 , 12 but it not working.
Assuming you actually meant subsequence, just guess the digit your sequence starts with and then run a linear scan. If you meant substring, it's even easier --- left as an exercise to OP.
The linear scan goes like this:
char next = <guessed digit>;
int len = 0;
char *ptr = <pointer to input string>;
while (*ptr) {
if ((*ptr) == next) {
next = next + 1;
if (next > '9') next = '0';
len++;
}
ptr++;
}
Now wrap that with a loop that sets to all digits from '0' to '9' and you are done, pick the one that gives the longest length.
simple idea: start point, end point and length of the sequence.
Run loop i
sequence will start whenever current number (at index i) less than next number 1 => start point set = i
it ends when condition above false => get end point => get the length = end -start (make more variable called max to compare lengths) => result could be max, reset start point, end point = 0 again when end of sequence
I made it myself:
#include <iostream>
using namespace std;
bool cons(int list[] , int iv) { bool ret=true; for (int a=0; a<=iv; a++) { if (list[a] != list[a+1]-1) ret=false; } return ret; }
void main() {
int str[10] = {12,13,15,16,17,18,20,21};
int longest=0;
int pos=0;
for (int lenght=1; lenght <= 9; lenght++) {
int li[10];
for (int seek=0; seek <= 9; seek++) {
for (int kor=0; kor <= lenght-1; kor ++ ) {
li[kor] = str[seek+kor];
}
if (cons(li , lenght-2)) {
longest = lenght;
pos=seek;
}
}
}
for (int b=pos; b <= pos+longest-1; b++) cout << str[b] << " - "; cout << "it is the end!" << endl; getchar();
}