ASCII math in C - ascii

In C i can't simply use putchar(5);
I have to do it like this
#include <stdio.h>
int main(){
int c=5;
putchar(c+'0');
putchar('\n');
return 0;
}
the output is 5.
But I can't do this for double digit numbers like 10 or 25.
My question is , is it possible to print out 10 using putchar and putchar only?
I can't do it like this
int c=10;
putchar(c+'0');
The output would be':' because ':' has the ASCII value of 58.

If it is only numbers you can try the below logic.
#include <stdio.h>
int main()
{
int c = 465, n = 0, i = 1;
while(c > 0){
n *= (10 * i);
n += (c % 10);
c /= 10;
}
do {
putchar((n % 10)+'0');
n /= 10;
} while(n > 0);
putchar('\n');
return 0;
}

Related

Using heap sort, append an array elements

I have given an array int A[] = {12,10,9,2,11,8,14,3,5};
In this array, 1st 4 elements(from index 0 to index 3) follow max heap condition. But last 5 elements(index 4 to index 8) don't follow max heap condition. So, I have to write a code so that the whole array follow max heap condition.
I have given a function call max_heap_append(A,3,8); and I have to use it in my code to write the program. It is an assignment so I have to follow the instruction.
I have written this code bellow but when I run the program, nothing happens.
#include <stdio.h>
#include <stdlib.h>
void swap(int * a, int * b )
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
void heapify( int A[], int q, int i)
{
int largest = i;
int l = 2 * i + 1 ;
int r = 2 * i + 2;
if( l < q && A[l] > A[largest])
{
largest = l;
}
if( r < q && A[r] > A[largest])
{
largest = r;
}
if( largest != i)
{
swap( &A[i] , &A[largest]);
heapify(A, q, largest);
}
}
void max_heap_append(int A[], int p , int q)
{
int i;
for( i = q / 2 -1; i >= 0; i--)
{
heapify( A , q , i);
}
// sort the heap
for( i = q; i>= 0; i--)
{
swap(&A[0] , &A[i]);
heapify(A, i, 0);
}
}
void printA(int A[], int q)
{
int i;
for( i = 0; i <= q; i++)
{
printf("%d", A[i]);
}
printf("%d\n");
}
int main()
{
int A[] = {12,10,9,2,11,8,14,3};
max_heap_append(A,3,8);
printf("Sorted: ");
printA(A, 8);
return 0;
}
Its not followed heapify from 0 to 3 index.. so u need to heapify all. there is some mistake. if your array size is 8 then u can not excess a[8], you can access a[0] to a[7]. so you need to iterate from 0 to 7.
Try with this:
#include <stdio.h>
#include <stdlib.h>
void swap(int * a, int * b )
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
void heapify( int A[], int q, int i)
{
int largest = i;
int l = 2 * i + 1 ;
int r = 2 * i + 2;
if( l < q && A[l] > A[largest])
{
largest = l;
}
if( r < q && A[r] > A[largest])
{
largest = r;
}
if( largest != i)
{
swap( &A[i] , &A[largest]);
heapify(A, q, largest);
}
}
void max_heap_append(int A[], int p , int q)
{
int i;
for( i = q-1; i >= 0; i--)
{
heapify( A , q , i);
}
// sort the heap
for( i = q-1; i>= 0; i--)
{
swap(&A[0] , &A[i]);
heapify(A, i, 0);
}
}
void printA(int A[], int q)
{
int i;
for( i = 0; i < q; i++)
{
printf("%d ", A[i]);
}
printf("\n");
}
int main()
{
int A[] = {12,10,9,2,11,8,14,3};
max_heap_append(A,3,8);
printf("Sorted: ");
printA(A, 8);
return 0;
}
You have several problems in your code
printA
One is/can be indicated by the compiler, in printA :
printf("%d\n");
‘%d’ expects a matching ‘int’ argument, but there no no argument
It is easy to guess you just wanted to print a newline, so that line can be replaced by
putchar('\n');
Still in printA you print the numbers without a separator, the result is not usable, for instance do
printf("%d ", A[i]);
When I look at the call of printA in main the parameter n is the number of elements in A, so the end test of the for is invalid because you try to print a value out of the array, the loop must be :
for( i = 0; i < q; i++)
max_heap_append
in the second for the index i can value 0, in that case you swap the first element of the array with itself, that has no sense and the same for the call of heapify with the 2 last arguments valuing 0
When you call that function in main the parameter q receive the number of elements in the array, which is also the first value of i still in that second for and &A[i] is out of the array. You need to replace that line by
for( i = q-1; i> 0; i--)
If I do all these changes :
Compilation and execution :
bruno#bruno-XPS-8300:/tmp$ gcc -g -Wall h.c
bruno#bruno-XPS-8300:/tmp$ ./a.out
Sorted: 2 3 8 9 10 11 12 14
bruno#bruno-XPS-8300:/tmp$

MPI_Scatterv submatrix with MPI_Type_struct

I'm currently working on a MPI-program and I'm trying to send blocks of a matrix with scatterv to all processes.
Process description
The matrix is given as an array.
First I produce a datatype with MPI_Type_vector to create the necessary block out of the original array.
Second I create a MPI_Type_struct that should hold rows of blocks.
#include <math.h>
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#define n 16
int main(int argc, char *argv[])
{
MPI_Init(&argc, &argv);
MPI_Comm comm = MPI_COMM_WORLD;
int p,r;
MPI_Comm_size(comm, &p);
MPI_Comm_rank(comm, &r);
int *arr;
arr = NULL;
if (r == 0){
arr = (int *) malloc(n * n * sizeof(int));
for (int i = 0; i < n * n; i++) arr[i] = i;
for (int i = 0; i < n; i++){
printf("\n");
for (int j = 0; j < n; j++)
printf("%4d", arr[i * n + j]);
}
}
printf("\n");
int ps = sqrt(p);
int ns = n / ps;
if (r == 0) {
printf("ps: %d ns: %d\n", ps, ns);
}
/* create datatype */
MPI_Datatype block;
MPI_Type_vector(ns, ns, n, MPI_INT, &block);
int blocks[ps];
MPI_Aint displs[ps];
for (int i = 0; i < ps; i++) {
blocks[i] = 1;
displs[i] = i * sizeof(int);
}
MPI_Datatype types[ps];
//for (int i = 0; i < ps - 1; i++) types[i] = block;
//types[ps - 1] = MPI_UB;
types[0] = block;
for (int i = 1; i < ps; i++) types[i] = MPI_UB;
//types[0] = block;
//types[1] = MPI_UB;
if (r == 0) {
printf("displs:\n");
for(int i = 0; i < ps; i++) printf("%3ld", displs[i]);
printf("\n");
}
MPI_Datatype row;
MPI_Type_struct(ps, blocks, displs, types, &row);
MPI_Type_commit(&row);
/* prepare scatter */
int sdispl[p]; int sendcounts[p];
for (int i = 0; i < p; i++) {
sdispl[i] = (i % ps) + (i / ps) * (ns * ps);
sendcounts[i] = 1;
}
if (r == 0) {
printf("sdispl: \n");
for (int i = 0; i < 4; i++) printf("%3d", sdispl[i]);
printf("\n");
}
int rcv[ns * ns];
MPI_Scatterv(arr, sendcounts, sdispl, row, rcv, ns * ns, MPI_INT, 0, comm);
int result = 1;
if (r == result) {
printf("result for %d:\n", result);
for (int i = 0; i < ns * ns; i++) {
printf("%4d", rcv[i]);
if ((i+1) % ns == 0) printf("\n");
}
}
if (arr != NULL) free(arr);
MPI_Finalize();
return 0;
}
So far the structure of the blocks is correct.
The problem
The block, that was sent to process r = 1 starts with 3 instead of 4. The block for process r = 2 also starts with 6 and the one for process r = 3 starts with 9.
For r == 4 it jumps to 48.
What it should do
r start
0 0
1 4
2 8
3 12
4 64
5 68
6 ...
15 204
The help I would need
I think, that I'm making some mistake with displ and sdispl.
Compiling and Running the example
The code is compiled with the folowing command:
mpicc -o main main.c -lm
I run the code with:
mpirun -np 16 ./main
Thanks for any help in advance!
With the hint of Zulan I was able to solve my problem.
The following code is based on the excellent answer to subarrays.
#include <math.h>
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#define n 8
void print_arr(int *arr, int x) {
printf("\n");
for (int i = 0; i < x*x; i++){
if (i % x == 0) printf("\n");
printf("%4d", arr[i]);
}
printf("\n");
}
int main(int argc, char *argv[])
{
MPI_Init(&argc, &argv);
MPI_Comm comm = MPI_COMM_WORLD;
int p, r;
MPI_Comm_size(comm, &p);
MPI_Comm_rank(comm, &r);
/* number of proceses in dim x and dim y */
int ps = sqrt(p);
/* number of elements in dim x and dim y in sarr */
int ns = n/ps;
/* array of data - distributed by process 0 */
int *arr = NULL;
if (r==0) {
arr = (int *) malloc(n * n * sizeof(int));
for (int i = 0; i < n*n; i++) arr[i] = i;
print_arr(arr, n);
}
MPI_Datatype type, resizedtype;
int sizes[2] = {n,n};
int subsizes[2] = {ns,ns};
int starts[2] = {0,0};
MPI_Type_create_subarray(2, sizes, subsizes, starts, MPI_ORDER_C, MPI_INT, &type);
MPI_Type_create_resized(type, 0, ns*sizeof(int), &resizedtype);
MPI_Type_commit(&resizedtype);
int counts[p];
for (int i = 0; i < p; i++) counts[i] = 1;
int displs[p];
for (int i = 0; i < p; i++) displs[i] = i%ps + i/ps * ns * ps;
/* subarray to store distributed data */
int sarr[ns * ns];
/* send submatrices to all processes */
MPI_Scatterv(arr, counts, displs, resizedtype, sarr, ns*ns, MPI_INT, 0, comm);
/* print received data for process pr */
int pr = 3;
if (r == pr)
print_arr(sarr, ns);
/* free arr */
if (arr != NULL) free(arr);
MPI_Finalize();
return 0;
}
You can compile the example with
mpicc -o main main.c
and run it with
mpirun -np 4 ./main

How to generate random values with fixed sum in C++

I want to generate 3 random numbers in the range 0 to 9 in a row which should sum up to a given fixed number. For example, for the given fixed sum 15, one possible solution would be (3, 8, 4). How can I do this ? Thanks.
We can:
First generate random float number a,b,c between 0 and 1
Get sum of a,b,c
Divide a,b,c by sum
Multiple a,b,c by given desired sum integer, and then round a,b,c to the nearest integer
See if sum(a, b, c) == given integer ? get result : try again
Check this demo:
Using boost random generator:
#include <iostream>
#include <time.h>
#include <iomanip>
#include <boost/random.hpp>
int main()
{
static time_t seed = time(0);
boost::random::mt19937 RandomNumGen(seed++);
boost::random::uniform_real_distribution<> Range(0, 1);
int Desired_Integer = 15;
int Rand_Max = 9;
int Max_Itr = 100000000;
int Count = 0;
int SumABC[3][10] = { 0 };
float bias = 0.5;
float a, b, c;
for (int Loop = 1; Loop <= Max_Itr; ++Loop)
{
a = Range(RandomNumGen);
b = Range(RandomNumGen);
c = Range(RandomNumGen);
float Sum = a + b + c;
a = a / Sum;
b = b / Sum;
c = c / Sum;
//Round to the nearest integer;
int aI = static_cast<int>(a * Desired_Integer + bias), bI = static_cast<int>(b * Desired_Integer + bias), cI = static_cast<int>(c * Desired_Integer + bias);
if (aI <= Rand_Max && bI <= Rand_Max && cI <= Rand_Max && aI + bI + cI == Desired_Integer)
{
SumABC[0][aI]++;
SumABC[1][bI]++;
SumABC[2][cI]++;
Count++;
}
}
int PaddingWidth = 10;
std::cout << "\n" << Count << " in " << Max_Itr << " loops get desired outcome. \nDistribution of a,b,c: \n";
std::cout << "Number" << std::setw(PaddingWidth) << "a" << std::setw(PaddingWidth) << "b" << std::setw(PaddingWidth) << "c" << std::endl;
for (int i = 0; i < 10; i++)
{
std::cout
<< i << std::setw(PaddingWidth + 8)
<< std::setprecision(4) << 100.0 * SumABC[0][i] / (float)Count << std::setw(PaddingWidth)
<< std::setprecision(4) << 100.0 * SumABC[1][i] / (float)Count << std::setw(PaddingWidth)
<< std::setprecision(4) << 100.0 * SumABC[2][i] / (float)Count << std::endl;
}
std::cout << "\n\n";
system("pause");
return 0;
}
Test efficiency:
When dealing with random variables it's a really good idea to check the work.
I simulated both answers. Xiaotao's not only has a different distribution, but different distribution frequencies. aI and bI have the same distribution but cI is significantly different. All three should have identical distributions.
Also, Kay's solution has the proper distribution as P(a)==1 s/b 1.25 times P(a)==1.
This is a deterministic solution and it has exactly the same statistics as Kay's
Further, the frequency of occurrence of each number looking at it purely from a probability POV from 0 to 9 is 4/73, 5/73, 6/73, 7/73, 8/73, 9/73, 10/73, 9/73, 8/73 and 7/73
A vector of all possible number sequences that sums to 15 is created. Then one element is chosen randomly. Each number set has an identical probability of being selected
#include <algorithm>
#include <array>
#include <iostream>
#include <numeric>
#include <random>
using namespace std;
// Your constants:
static constexpr unsigned DICE_COUNT = 3;
static constexpr unsigned DICE_SIDES = 10;
static constexpr unsigned DESIRED_NUMBER = 15;
int main() {
// Initialize your PRNG:
vector<array<int, 3>> allLegalNumbers;
for (int i=0; i <= 9; i++) // go through all possible sets of 3 numbers from 0 to 9
for (int ii = 0; ii < DICE_SIDES; ii++)
for (int iii = 0; iii < DICE_SIDES; iii++)
if (i + ii + iii == DESIRED_NUMBER) // keep the ones that add up to 15
allLegalNumbers.push_back(array<int, 3> {i, ii, iii});
random_device rd;
mt19937 generator(rd());
uniform_int_distribution<unsigned> distribution(0, allLegalNumbers.size() - 1);
int sum[3][DICE_SIDES]{};
int sum_count = 0;
for (int Loop = 1; Loop < 100000000; ++Loop)
{
auto index = distribution(generator);
sum[0][allLegalNumbers[index][0]]++;
sum[1][allLegalNumbers[index][1]]++;
sum[2][allLegalNumbers[index][2]]++;
sum_count++;
}
for (int i = 0; i < DICE_SIDES; i++)
printf("Percent of aI==%d:%5.2f bI==%d:%5.2f cI==%d:%5.2f\n",
i, 100.0*sum[0][i] / sum_count,
i, 100.0*sum[1][i] / sum_count,
i, 100.0*sum[2][i] / sum_count);
return 0;
}
/* Results:
Percent of aI==0: 5.48 bI==0: 5.48 cI==0: 5.48
Percent of aI==1: 6.85 bI==1: 6.85 cI==1: 6.85
Percent of aI==2: 8.22 bI==2: 8.22 cI==2: 8.22
Percent of aI==3: 9.59 bI==3: 9.59 cI==3: 9.59
Percent of aI==4:10.96 bI==4:10.96 cI==4:10.96
Percent of aI==5:12.33 bI==5:12.33 cI==5:12.34
Percent of aI==6:13.69 bI==6:13.70 cI==6:13.70
Percent of aI==7:12.34 bI==7:12.33 cI==7:12.33
Percent of aI==8:10.96 bI==8:10.96 cI==8:10.95
Percent of aI==9: 9.59 bI==9: 9.59 cI==9: 9.58
*/
Xiaotao's answer simulation: Note the different distribution of cI v aI and bI
#include <iostream>
int main()
{
int SumI = 15;
int Rand_Max = 9;
float a, b, c;
int sum[3][10]{};
int sum_count = 0;
for (int Loop = 1; Loop < 100000000; ++Loop)
{
a = static_cast<float>(rand() % Rand_Max) / static_cast<float>(Rand_Max);
b = static_cast<float>(rand() % Rand_Max) / static_cast<float>(Rand_Max);
c = static_cast<float>(rand() % Rand_Max) / static_cast<float>(Rand_Max);
float Sum = a + b + c;
a = a / Sum;
b = b / Sum;
c = c / Sum;
//Round to the nearest integer;
int aI = static_cast<int>(a * SumI + 0.5), bI = static_cast<int>(b * SumI + 0.5), cI = static_cast<int>(c * SumI + 0.5);
if (aI <= Rand_Max && bI <= Rand_Max && cI <= Rand_Max && aI + bI + cI == SumI)
{
sum[0][aI]++;
sum[1][bI]++;
sum[2][cI]++;
sum_count++;
}
}
for (int i = 0; i < 10; i++)
printf("Percent of aI==%d:%5.2f bI==%d:%5.2f cI==%d:%5.2f\n",
i, 100.0*sum[0][i] / sum_count,
i, 100.0*sum[1][i] / sum_count,
i, 100.0*sum[2][i] / sum_count);
return 0;
}
/* Results:
Percent of aI==0: 5.84 bI==0: 5.83 cI==0: 5.84
Percent of aI==1: 5.30 bI==1: 5.31 cI==1: 5.31
Percent of aI==2: 7.43 bI==2: 7.43 cI==2: 6.90
Percent of aI==3: 9.55 bI==3: 9.54 cI==3: 9.28
Percent of aI==4:10.61 bI==4:10.61 cI==4:10.60
Percent of aI==5:15.64 bI==5:15.66 cI==5:15.39
Percent of aI==6:16.18 bI==6:16.18 cI==6:17.51
Percent of aI==7:11.41 bI==7:11.40 cI==7:10.88
Percent of aI==8: 9.82 bI==8: 9.81 cI==8:10.08
Percent of aI==9: 8.22 bI==9: 8.22 cI==9: 8.22
*/
Kay's answer does not exhibit this error. Here's that simulation:
#include <algorithm>
#include <array>
#include <iostream>
#include <numeric>
#include <random>
// Don't use "using namespace" in production.
// I only use it to avoid the horizontal scrollbar.
using namespace std;
// Your constants:
static constexpr unsigned DICE_COUNT = 3;
static constexpr unsigned DICE_SIDES = 10;
static constexpr unsigned DESIRED_NUMBER = 15;
int main() {
// Initialize your PRNG:
random_device rd;
mt19937 generator(rd());
uniform_int_distribution<unsigned> distribution(0, DICE_SIDES - 1);
int sum[3][10]{};
int sum_count = 0;
for (int Loop = 1; Loop < 10000000; ++Loop)
{
// Fill the array with three random numbers until you have a match:
array<unsigned, DICE_COUNT> values = { 0 };
while (accumulate(begin(values), end(values), 0) != DESIRED_NUMBER) {
for_each(begin(values), end(values), [&](unsigned &v) {
v = distribution(generator);
//v = rand() % DICE_SIDES; // substitute this to use rand()
});
}
sum[0][values[0]]++;
sum[1][values[1]]++;
sum[2][values[2]]++;
sum_count++;
}
for (int i = 0; i < 10; i++)
printf("Percent of aI==%d:%5.2f bI==%d:%5.2f cI==%d:%5.2f\n",
i, 100.0*sum[0][i] / sum_count,
i, 100.0*sum[1][i] / sum_count,
i, 100.0*sum[2][i] / sum_count);
return 0;
}
/* Results:
Percent of aI==0: 5.48 bI==0: 5.48 cI==0: 5.47
Percent of aI==1: 6.85 bI==1: 6.85 cI==1: 6.85
Percent of aI==2: 8.22 bI==2: 8.19 cI==2: 8.22
Percent of aI==3: 9.60 bI==3: 9.59 cI==3: 9.60
Percent of aI==4:10.97 bI==4:10.96 cI==4:10.99
Percent of aI==5:12.34 bI==5:12.32 cI==5:12.32
Percent of aI==6:13.69 bI==6:13.70 cI==6:13.71
Percent of aI==7:12.31 bI==7:12.34 cI==7:12.30
Percent of aI==8:10.95 bI==8:10.96 cI==8:10.95
Percent of aI==9: 9.60 bI==9: 9.60 cI==9: 9.59
*/
Here's a tutorial how to generate random numbers in C++11: http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
The easiest solution is to try it until you find a match:
#include <algorithm>
#include <array>
#include <iostream>
#include <numeric>
#include <random>
// Don't use "using namespace" in production.
// I only use it to avoid the horizontal scrollbar.
using namespace std;
// Your constants:
static constexpr unsigned DICE_COUNT = 3;
static constexpr unsigned DICE_SIDES = 10;
static constexpr unsigned DESIRED_NUMBER = 15;
int main() {
// Initialize your PRNG:
random_device rd;
mt19937 generator(rd());
uniform_int_distribution<unsigned> distribution(0, DICE_SIDES - 1);
// Fill the array with three random numbers until you have a match:
array<unsigned, DICE_COUNT> values = { 0 };
while (accumulate(begin(values), end(values), 0) != DESIRED_NUMBER) {
for_each(begin(values), end(values), [&](unsigned &v) {
v = distribution(generator);
});
}
// Print the result:
for_each(begin(values), end(values), [&](unsigned &v) {
cout << v << ' ';
});
cout << endl;
return 0;
}
You'll need about nine iterations to have a 50/50 chance that you'll throw a 15:
P(3d10 = 18) ≈ 1/14 (+3 to account for the range shift)
(13/14)^n < 0.5 → n ≈ 9.4

c++ - how to convert char to int?

I try to write a function who convert a string to an integer (like atoi). I don't see why my function "convertir" don't print my variable "res " whereas "test 1 " "test 2"... "test 4" is printed. I let you look at my code and if you see something bad tell me please.
#include "stdio.h"
#include "stdlib.h"
int xpown(int x, int n); // x^n
int lent(char str[]); // return length of string
int convertir(char s[]); //convert char to int
int main(){
char s[] ="1234";
convertir(s);
return 0;
}
int xpown(int x, int n){
int res = 1;
while (n != 1){
res= res*x;
n--;
}
return res;
}
int lent(char str[]){
int res =0;
int i=0;
while (str[i] != '\0'){
res=res+1;
i++;
}
return res;
}
int convertir(char s[]){
int res = 0;
int i = lent(s);
int j = 0;
char c = s[j];
while (c != '\0'){
c=s[j];
printf("test %d \n", j);
res = res + (c - 48) * xpown(10,i);
i--;
j++;
}
printf("%d", res);
}
You're setting i too high. Consider the simplest case, where s has 1 digit. You want to multiply that digit by 1 (100), not 10 (101). So it should be:
int i = lent(s) - 1;
BTW, you shouldn't hard code the value 48, use '0':
res += (c - '0') * xpown(10, i);
The standard function atoi() will likely do what you want.

Find longest non-decreasing sequence

Given the following question,
Given an array of integers A of length n, find the longest sequence {i_1, ..., i_k} such that i_j < i_(j+1) and A[i_j] <= A[i_(j+1)] for any j in [1, k-1].
Here is my solution, is this correct?
max_start = 0; // store the final result
max_end = 0;
try_start = 0; // store the initial result
try_end = 0;
FOR i=0; i<(A.length-1); i++ DO
if A[i] <= A[i+1]
try_end = i+1; // satisfy the condition so move the ending point
else // now the condition is broken
if (try_end - try_start) > (max_end - max_start) // keep it if it is the maximum
max_end = try_end;
max_start = try_start;
endif
try_start = i+1; // reset the search
try_end = i+1;
endif
ENDFOR
// Checking the boundary conditions based on comments by Jason
if (try_end - try_start) > (max_end - max_start)
max_end = try_end;
max_start = try_start;
endif
Somehow, I don't think this is a correct solution but I cannot find a counter-example that disapprove this solution.
anyone can help?
Thank you
I don't see any backtracking in your algorithm, and it seems to be suited for contiguous blocks of non-decreasing numbers. If I understand correctly, for the following input:
1 2 3 4 10 5 6 7
your algorithm would return 1 2 3 4 10 instead of 1 2 3 4 5 6 7.
Try to find a solution using dynamic programming.
You're missing the case where the condition is not broken at its last iteration:
1, 3, 5, 2, 4, 6, 8, 10
You'll never promote try_start and try_end to max_start and max_end unless your condition is broken. You need to perform the same check at the end of the loop.
Well, it looks like you're finding the start and the end of the sequence, which may be correct but it wasn't what was asked. I'd start by reading http://en.wikipedia.org/wiki/Longest_increasing_subsequence - I believe this is the question that was asked and it's a fairly well-known problem. In general cannot be solved in linear time, and will also require some form of dynamic programming. (There's an easier n^2 variant of the algorithm on Wikipedia as well - just do a linear sweep instead of the binary search.)
#include <algorithm>
#include <vector>
#include <stdio.h>
#include <string.h>
#include <assert.h>
template<class RandIter>
class CompM {
const RandIter X;
typedef typename std::iterator_traits<RandIter>::value_type value_type;
struct elem {
value_type c; // char type
explicit elem(value_type c) : c(c) {}
};
public:
elem operator()(value_type c) const { return elem(c); }
bool operator()(int a, int b) const { return X[a] < X[b]; } // for is_sorted
bool operator()(int a, elem b) const { return X[a] < b.c; } // for find
bool operator()(elem a, int b) const { return a.c < X[b]; } // for find
explicit CompM(const RandIter X) : X(X) {}
};
template<class RandContainer, class Key, class Compare>
int upper(const RandContainer& a, int n, const Key& k, const Compare& comp) {
return std::upper_bound(a.begin(), a.begin() + n, k, comp) - a.begin();
}
template<class RandIter>
std::pair<int,int> lis2(RandIter X, std::vector<int>& P)
{
int n = P.size(); assert(n > 0);
std::vector<int> M(n);
CompM<RandIter> comp(X);
int L = 0;
for (int i = 0; i < n; ++i) {
int j = upper(M, L, comp(X[i]), comp);
P[i] = (j > 0) ? M[j-1] : -1;
if (j == L) L++;
M[j] = i;
}
return std::pair<int,int>(L, M[L-1]);
}
int main(int argc, char** argv)
{
if (argc < 2) {
fprintf(stderr, "usage: %s string\n", argv[0]);
return 3;
}
const char* X = argv[1];
int n = strlen(X);
if (n == 0) {
fprintf(stderr, "param string must not empty\n");
return 3;
}
std::vector<int> P(n), S(n), F(n);
std::pair<int,int> lt = lis2(X, P); // L and tail
int L = lt.first;
printf("Longest_increasing_subsequence:L=%d\n", L);
for (int i = lt.second; i >= 0; --i) {
if (!F[i]) {
int j, k = 0;
for (j = i; j != -1; j = P[j], ++k) {
S[k] = j;
F[j] = 1;
}
std::reverse(S.begin(), S.begin()+k);
for (j = 0; j < k; ++j)
printf("%c", X[S[j]]);
printf("\n");
}
}
return 0;
}

Resources