I have an array like this:
600
250
600
600
600
I want to define the begin and the end indexes of this array where the value is greather than 500.
I made a variable which value is 2, because there are two section in my array where the values are greather than 500 (1-1 and 3-5).
So how could I output this:
1 1 3 5
The first 1 means the begin index is 1, the second 1 means the end index is also 1.
The 3 means the next section begin index where the value is greather than 500 is 3.
And the 5 means the end index of the second section is 5.
Using std:
std::vector<std::pair<std::size_t, std::size_t>>
compute_range_greater_than(const std::vector<int>& v, int threshold)
{
std::vector<std::pair<std::size_t, std::size_t>> res;
for (auto it = v.begin(); it != v.end(); /*Empty*/)
{
auto beg = std::find_if(it, v.end(), [=](int i) { return !(i < threshold); });
if (beg == v.end()) {
return res;
}
it = std::find_if(beg, v.end(), [=](int i) { return i < threshold; });
// using 1-index
res.push_back({1 + std::distance(v.begin(), beg), std::distance(v.begin(), it)});
}
return res;
}
Live Demo
Try this:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v;
v.push_back(10);
v.push_back(200);
v.push_back(170);
v.push_back(160);
v.push_back(20);
v.push_back(300);
v.push_back(12);
v.push_back(230);
std::vector<int> indexes;
int limit = 150;
bool started = false;
for (int i = 0; i < v.size(); i++)
{
int value = v[i];
if (value > limit && !started)
{
started = true;
indexes.push_back(i);
}
else if (value < limit && started)
{
started = false;
indexes.push_back(i - 1);
}
}
if (started)
indexes.push_back(v.size() - 1);
for (int i = 0; i < indexes.size(); i++)
{
if (i % 2 == 0)
std::cout << indexes[i] << "-";
else
std::cout << indexes[i] << "; ";
}
return 0;
}
Here limit is 150, but you can change it. Output is
1-3; 5-5; 7-7;
Good luck :)
You really should consider improving your question by better explaining what you want to do and by providing code that you already wrote (and if you didnt you should do it). However, I am in a good mood, so here you go:
#include <vector>
#include <iostream>
struct BeginAndEndIndex{
int begin;
int end;
BeginAndEndIndex(int begin) : begin(begin),end(begin) {}
};
typdef std::vector<BeginAndEndIndex> IndexV;
typdef std::vector<int> IV;
IndexV findBeginAndEndIndex(const IV& in,int threshold){
IndexV result;
bool isBiggerThanThreshold = false;
for (int i=0;i<in.size();i++){
if (!isBiggerThanThreshold) {
if (in[i]>threshold){
result.push_back(BeginAndEndIndex(i));
isBiggerThanThreshold = true;
}
} else {
if (in[i]<threshold){
result.back().end = i-1;
isBiggerThanThreshold = false;
}
}
}
if (isBiggerThanThreshold){result.back().end = in.size()-1;}
return result;
}
int main(void) {
IV foo {600,250,600,600,600};
IndexV bar = findBeginAndEndIndex(foo,500);
for (int i=0;i<bar.size();i++){
std::cout << bar[i].begin << " " << bar[i].end << std::endl;
}
return 0;
}
I am pretty sure that there is a more elegant way to implement it by using std::algorithms.
Just in straight C and not storing the indices anywhere, the following code produces the exact output that you are asking for:
#include <stdio.h>
int main(int argc, char **argv)
{
int values[] = {600, 250, 600, 600, 600};
int threshhold = 500;
int begIndex = -1;
int endIndex = -1;
int i;
for (i = 0; i < sizeof(values)/sizeof(values[0]); i++)
{
if (values[i] > threshhold)
{
if (begIndex < 0)
{
begIndex = i;
}
endIndex = i;
}
else if (begIndex >= 0)
{
printf("%d %d ", begIndex + 1, endIndex + 1);
begIndex = endIndex = -1;
}
}
if (begIndex >= 0)
printf("%d %d", begIndex + 1, endIndex + 1);
printf("\n");
return 0;
}
Keep in mind the arrays in C/C++ start at zero, not one. Changing the above code to store the begIndex and endIndex pairs should be a trivial operation.
Related
I have problem with the constraint
I have to partition it to "exact" k "different" integers
e.g. 10 = 1+2+7 -> valid
10 = 2+2+6 -> invalid
I don't want to print them, I want to store them in to vectors or something
I am thinking of recursive solution, but still can't come up with a efficient way to store them...(the solution I found can only print it)
And I think it should store in vector<vector>
the struct should be like this?
Partition(){
....
....
}
Partition_main(){
...
Partition()
....
}
In practice, the problem is to enumerate all the solutions.
This can be done by a DFS.
In the following code, the DFS is implemented with a help of a FIFO (i.e. a std::queue).
The little trick is, for a given candidate at a given step, to calculate the minimum
sum that can be obtained in the next steps.
If this minimum sum is larger than n, then we can stop the research in this direction.
#include <iostream>
#include <vector>
#include <queue>
#include <cassert>
struct Parti {
std::vector<int> v;
int sum = 0;
};
std::vector<std::vector<int>> get_partitions (int n, int k) {
std::vector<std::vector<int>> result;
std::queue<Parti> fifo;
Parti start;
fifo.push(start);
while (!fifo.empty()) {
Parti elt = fifo.front();
fifo.pop();
int sum = elt.sum;
int remain = k-elt.v.size();
if (remain == 1) {
int last = n - sum;
if (k > 1) assert (last > elt.v.back());
elt.v.push_back(last);
result.push_back (elt.v);
continue;
}
int i;
if (elt.v.size() == 0) i = 1;
else i = elt.v.back() + 1;
while (true) {
int min_sum = sum + remain*(2*i + remain - 1)/2;
if (min_sum > n) break;
Parti new_elt = elt;
new_elt.v.push_back(i);
new_elt.sum += i;
fifo.push (new_elt);
++i;
};
}
return result;
}
int main() {
int n = 15;
int k = 4;
auto res = get_partitions (n, k);
if (res.size() == 0) {
std::cout << "no partition possible\n";
return 0;
}
for (const auto& v: res) {
std::cout << n << " = ";
for (int i = 0; i < v.size(); ++i) {
std::cout << v[i];
if (i == v.size()-1) {
std::cout << "\n";
} else {
std::cout << " + ";
}
}
}
return 0;
}
I need to find position of string in substring. Scan has to begin from the end. For example:
findch(L"asdhuifdsahdfasasd", L"asd");
return 16 instead of 1
Here is my function:
int findchr(LPCWSTR T, LPCWSTR P)
{
int n = lstrlenW(T);
int m = lstrlenW(P);
for (int i = 0; i <= n - m; ++i) {
int j = 0;
while (j < m && T[i + j] == P[j]) {
++j;
}
if (j == m) {
return i;
}
}
return -1;
}
You can try using std::string::rfind which does exactly what you want:
Finds the last substring equal to the given character sequence.
Then you can have something like this:
#include <string>
#include <iostream>
std::string::size_type reverse_find(std::string const& str, std::string const& substr) {
return str.rfind(substr);
}
int main() {
auto first = reverse_find("asdhuifdsahdfasasd", "asd");
if (std::string::npos != first) {
std::cout << first << std::endl; // 15
}
auto second = reverse_find("asdhuifdsahdfasasd", "z");
if (std::string::npos != second) {
std::cout << second << std::endl; // won't be outputted
}
return 0;
}
Demo
Above reverse_find function returns 15 because indices start at 0.
int findchr(LPCWSTR str, LPCWSTR substr)
{
int n = lstrlenW(str);
int m = lstrlenW(substr);
for (int i = n; i >= m - n; --i) {
int j = 0;
while (j < m && str[i + j] == substr[j]) {
++j;
}
if (j == m) {
return i;
}
}
return -1;
}
A C++ program to compute and display all Armstrong numbers (numbers such that the sum of each of the digits raised to the power of the number of digits equals the number) between 100 and 999. The answers should be 153, 370, 371, 407. It prints all but 153.
Debugging done to see what the values of the individual digits are for i = 153.
#include <iostream>
#include <vector>
#include <math.h>
void separateDigits(int n, std::vector<int>& digits)
{
if (n>0)
{
separateDigits(n/10, digits);
digits.push_back(n%10);
}
}
int main()
{
for (int i = 100; i <= 999; i++)
{
std::vector<int> test;
separateDigits(i, test);
int powerSum = 0;
for (auto iter = test.begin(); iter != test.end(); iter++)
{
//powerSum = powerSum + pow((*iter),3);
powerSum = powerSum + (*iter)*(*iter)*(*iter);
}
if (i==powerSum)
{
std::cout << "Armstrong: " << i << std::endl;
}
}
return 0;
}
#include <stdio.h> //PROGRAM TO FIND ARMSRONG NUMBERS.
#include <math.h> //WORKS ONLY FOR THREE DIGIT NUMBERS.
int main()
{
int num, dig1, dig2, dig3;
for (num = 1; num <= 999; num++)
{
dig3 = dig2 = dig1 = 0;
dig3 = num % 10;
dig2 = ((num - dig3) % 100) / 10;
dig1 = (num - (dig3 + 10 * dig2)) / 100;
if (num == pow(dig1, 3) + pow(dig2, 3) + pow(dig3, 3))
{
printf("%d\n", num);
}
}
return 0;
}
This doesn't seem like your best option:
powerSum = powerSum + (*iter)*(*iter)*(*iter);
as you've now embedded your previous constant 3:
powerSum = powerSum + pow((*iter),3);
in an evem more obscure fashion. Why not consider a cleaner way that also supports numbers of sizes other than three digits:
unsigned digitsSize = test.size();
for (auto iter = test.begin(); iter != test.end(); iter++)
{
unsigned power = 1;
for (unsigned size = 0; size < digitsSize; size++) {
power *= *iter;
}
powerSum += power;
}
The complete code:
#include <iostream>
#include <vector>
void separateDigits(unsigned number, std::vector<unsigned>& digits)
{
while (number > 0)
{
digits.push_back(number % 10);
number /= 10;
}
}
int main()
{
std::vector<unsigned> digits;
for (unsigned number = 100; number <= 999; number++)
{
separateDigits(number, digits);
unsigned powerSum = 0, digitsSize = digits.size();
for (std::vector<unsigned>::iterator iter = digits.begin(); iter != digits.end(); iter++)
{
unsigned power = 1;
for (unsigned size = 0; size < digitsSize; size++) {
power *= *iter;
}
powerSum += power;
}
if (number == powerSum)
{
std::cout << "Armstrong: " << number << std::endl;
}
digits.clear();
}
return 0;
}
Changing the range from 100 - 999 to 1000 - 9999, no longer breaks the code, but instead produces:
> ./a.out
Armstrong: 1634
Armstrong: 8208
Armstrong: 9474
>
I want to find duplicate numbers in a row (2 in a row, 3 in a row, ...) in a randomly generated array. I can't make it further than this:
#include "stdafx.h"
#include <iostream>
#include <cstring>
#include <ctime>
#include <array>
#include <algorithm>
using namespace std;
int main()
{
srand(time(NULL));
const int velikostPolja = 100;
int a[velikostPolja];
int y = 0;
int x = 0;
for (int i = 0; i < velikostPolja; i++)
{
a[i] = rand() % 10;
cout << a[i];
}
cout << endl;
for (int i = 0; i < velikostPolja; i++)
{
if (a[i] == a[i + 1])
x++;
}
cout << endl;
cout << "Two times repated in row: " << x << endl;
system("pause");
return 0;
}
You could do it like this:
int count[velikostPolja] = { 0 };
int c = 0;
for (int i = 1; i < velikostPolja; i++)
{
if (a[i] == a[i - 1])
{
++c;
}
else
{
++count[c];
c = 0;
}
}
for (int i = 1; i < velikostPolja; i++)
{
if (count[i])
{
cout << i + 1 << " times repeated in row: " << count[i] << endl;
}
}
This does not account for any repeats at the end of a, though. I leave that as an exercise for you to do yourself.
You might use:
template <typename IT>
std::size_t count_repetition(IT begin, IT end, std::size_t count)
{
std::size_t res = 0;
auto it = begin;
while (it != end) {
it = std::adjacent_find(it, end);
if (it == end){
return res;
}
const auto it2 = std::find_if(it, end, [it](const auto& e) { return e != *it; });
const auto dist = std::distance(it, it2);
if (count <= dist) {
// how to count 2-repetition for {a, a, a, a}
#if 0
++res; // Count only as 1
#else
res += dist + 1 - count; // count as 3
#endif
}
it = it2;
}
return res;
}
Demo
What is the most efficient way to check whether you can create an arithmetic sequence from the specified sequence of numbers?
Currently I sort the sequence and then do this:
#include<bits/stdc++.h>
using namespace std;
static bool sort_using_greater_than(float u, float v)
{
return u > v;
}
int main()
{
int licznik=0, i=0;
double number[100000];
while(~scanf("%f", &number[i]))
{
i++;
licznik++;
}
sort(number,number+100, sort_using_greater_than);
for(int i = 1; i < licznik-1; i++)
{
if(number[i] - number[i+1] != number[0] - number[1])
{
puts("NO");
return 0;
}
}
puts("YES");
}
For test:
1.0 5.0
My code return YES, why?
enter code here
double search_min(double tab[], int n)
{
double min = tab[0];
for(int i = 1; i < n; i++)
{
if(min > tab[i])
min = tab[i];
return min;
}
And, How I can find two smallest element?
The question is unclear but if it means "check that the given numbers can be rearranged to from a single arithmetic sequence", then there is no need to sort.
find the smallest element, in O(N), let a;
find the second smallest, in O(N), let b;
clear an array of N bits in O(N);
for every number c, compute (c - a) / (b - a); if this isn't an integer in range [0,n-1], the answer is no. Otherwise, set the bit at that index (done in O(1) per element);
check that all bits have been set in O(N).
The whole process takes time O(N).
O(n) is the best you are going to get simply by the nature that you must check every element.
I've implemented Yves Daoust's algorithm (with some minor optimizations) as well as your own in C++14 standard code.
Here is yours:
int main(int argc, char* argv[]) {
if(argc == 1) return 0;
//Copy command args to vector of strings.
std::size_t number_count = argc - 1;
std::vector<std::string> cmd_args(number_count);
std::copy(argv + 1, argv + argc, cmd_args.begin());
//Copy convert vector of strings to vector of ints.
std::vector<int> values(number_count);
auto v_begin = values.begin();
for(auto s : cmd_args) {
(*v_begin) = std::stoi(s);
++v_begin;
}
//Sort values in ascending order.
std::sort(values.begin(), values.end());
//Get smallest two values.
std::pair<int, int> two_smallest_values(*values.cbegin(), *(values.cbegin() + 1));
//Calculate differences between each successive number
std::vector<int> differences(values.size() - 1);
for(std::size_t i = 0; i < values.size() - 1; ++i) {
differences[i] = std::abs(values[i] - values[i + 1]);
}
//All values in differences must be the same.
if(std::all_of(differences.cbegin(), differences.cend(), [=](int i) { return i == *differences.cbegin(); })) {
std::cout << "YES\n";
} else {
std::cout << "NO\n";
}
return 0;
}
Here is Yves Daoust's algorithm:
int main(int argc, char* argv[]) {
if(argc == 1) return 0;
//Copy command args to vector of strings.
std::size_t number_count = argc - 1;
std::vector<std::string> cmd_args(number_count);
std::copy(argv + 1, argv + argc, cmd_args.begin());
//Copy convert vector of strings to vector of ints.
auto v_begin = values.begin();
for(auto s : cmd_args) {
(*v_begin) = std::stoi(s);
++v_begin;
}
//Sort values in ascending order.
std::sort(values.begin(), values.end());
//Get smallest two values.
std::pair<int, int> two_smallest_values(*values.cbegin(), *(values.cbegin() + 1));
std::vector<bool> bits(values.size());
bool result = true;
int smallest_diff = (two_smallest_values.second - two_smallest_values.first);
for(auto v : values) {
int numerator = v - two_smallest_values.first;
int denominator = smallest_diff;
if(numerator % denominator != 0) {
result = false;
break;
}
std::size_t i = numerator / denominator;
if(i < 0 || i >= values.size()) {
result = false;
break;
}
bits[i] = true;
}
if(result == false) {
std::cout << "NO\n";
return 0;
}
//Convert vector of bools (bit-packed) to an unsigned int.
unsigned long long bits_value = 0;
unsigned long long i = 0;
for(auto b : bits) {
bits_value |= (b << i++);
}
//Optimization: Single calculation to determine if all bits are set:
if(std::abs(bits_value - (std::pow(2.0, bits.size()) - 1) < 0.01)) {
std::cout << "YES\n";
} else {
std::cout << "NO\n";
}
return 0;
}