c++ vector sorting with row and first column - sorting

i have a 2d vector 10*100, with totally 1000 integers.
i want to sort the numbers by row and then by the first column containing every smallest number in each row after sorting by row.
then i want to find the smallest in the first column and store it in a new vector, at the same time erase this smallest num in that row, the rest numbers move forward and keep going in this way. but my code always has problems, i am a beginner, i can not fix it even after i have tried more than 20 times.
please help me out!!!
vector<int> final;
vector<int> firstcol;
for (int j=0; j<vec.size(); j++) {
firstcol.push_back(vec[j][0]);
cout << firstcol[j]<< endl;
}
int mini = *firstcol.begin();
for(int k=0; k< firstcol.size();k++){
while (firstcol[k]< mini) {
mini=firstcol[k];
final.push_back(mini);
}
vec[k].erase(vec[k].begin());
}
cout << "mini:" << mini<<endl;
for (int m=0; m< final.size(); m++) {
cout << final[m]<<endl;
}

Related

I have to make a program that sorts 15 numbers from greatest to least, and then list the top five

I have to make a program that sorts 15 numbers from greatest to least, and then list the top five. Ive gotten some of it done. can someone help me on how to list the top five numbers?
#include <iostream>
using namespace std;
#define MAX 100
int main()
{
int arr[MAX];
int n,i,j;
int temp;
cout<<"Enter how many numbers to read: ";
cin>>n;
for(i=0;i<n;i++)
{
cout<<"Enter "<<i+1<<" number ";
cin>>arr[i];
}
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(arr[i]<arr[j])
{
temp =arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
cout<<"largest to smallest:"<<endl;
for(i=0;i<n;i++)
cout<<arr[i]<<"\t";
cout<<endl;
cout <<"the top five numbers are:"<< endl;
return 0;
}
Well you have already sorted it in descending order.
So to get the top 5, you just have to print the first 5 numbers in your array.
for (i=0; i<5; i++) cout << arr[i] << endl;
If you only need to have the top 5 elements, it is not necessary to sort the whole array. You can do a std::partial_sort to just have top 5 elements.
std::partial_sort(
std::begin(arr),
std::begin(arr) + 5,
std::end(arr),
[](int x, int y) { return x > y; });

Why this code is giving segmentation fault?

Alice is playing an arcade game and wants to climb to the top of the leaderboard and wants to track her ranking. Its leaderboard works like this:
-The player with the highest score is ranked number on the leaderboard.
-Players who have equal scores receive the same ranking number, and the next player(s) receive the immediately following ranking number.
For example, the four players on the leaderboard have high scores of 100, 90, 90 and 80. Those players will have ranks 1, 2, 2 and 3 respectively. If Alice's scores are 70, 80 and 105 her rankings after each game are 4th, 3rd and 1st.
#include <bits/stdc++.h>
using namespace std;
struct table{
int rank;
int score;
};
This is a modified binary search function iplementation for searching the score.
int search(vector<table> v,int low,int high,int n,int x){
if(low<=high){
int mid =(high+low)/2;
if((v[mid].score==x) || (mid==0 && v[mid].score<x))
return v[mid].rank;
if(mid==n-1 && v[mid].score>x)
return (v[mid].rank + 1);
if(v[mid].score>x && x>v[mid+1].score && mid<n-1)
return v[mid+1].rank;
if(v[mid].score>x)
return search(v,mid+1,high,n,x);
else
return search(v,low,mid-1,n,x);
}
return -1;
}
Main climbingLeaderboard function
vector<int> climbingLeaderboard(vector<int> scores, vector<int> alice) {
vector<table> v;
vector<int> res;
int n = scores.size();
int m = alice.size();
int x=1;
for(int i=0 ; i<n ; i++){
if(scores[i]!=scores[i-1] && i>0)
x++;
v[i].rank = x;
v[i].score = scores[i];
}
int z;
for(int i=0 ; i<m ; i++){
x=alice[i];
z = search(v,0,n-1,n,x);
res.push_back(z);
}
return res;
}
Driver Program
int main(){
int scores_count;
cin >> scores_count;
vector<int> scores; `//vector for storing leaderboard scores`
int k;
for(int i=0 ; i<scores_count ; i++){
cin >> k;
scores.push_back(k);
}
int game_count; `//number of games played by alice`
vector<int> Alice; `//vector for storing Alice's scores`
for(int i=0 ; i<game_count ; i++){
cin >> k;
alice.push_back(k);
}
vector<int> result; `//vector for storing result rank of each game of Alice`
result = climbingLeaderboard(scores,alice);
for(auto i = result.begin() ; i!=result.end() ; i++){
cout << *i << endl;
}
return 0;
}
Problem: In your climbingLeaderboard function, the first loop will attempt to access scores[i-1] when i is set to 0, resulting in a negative index for a std::vector access.
Fix: Change the for loop to start from i=1.
Problem 2: You access v by index without instantiating any structures to hold the data (e.g. v[i].rank = x).
Fix 2: Create an instance of the structure and write the data to it, then push it back into the vector v. Alternatively, reserve the memory for the whole vector as a preallocation.
Problem 3: On closer inspection, your search functionality is definitely broken. You should probably test this in isolation from the rest of the code.
Core Dump/Segmentation fault is a specific kind of error caused by accessing memory that does not belong to you.
Error in function:Main climbingLeaderboard function:
Accessing out of array index bounds
Start Loop From I =1 as you are doing score[i-1] which here in the first iteration would score[-1] (index) and there is no -1 index in c++
for(int i=1; i<n ; i++){
if(scores[i]!=scores[i-1] && i>0)
x++;
v[i].rank = x;
v[i].score = scores[i];
}

Algorithm to remove unique elements from array and print elements in original order

There is one question which is bugging me, and somehow, I cannot figure out what to do with it. Suppose an array {9,1,2,4,1,2,2} is given. The unique elements in the array are 9 and 4. The output array should be {1,2,1,2,2} .
My idea to preserve the order and find duplicates is to use a LinkedHashMap which will have the entries and the count of occurrence of the entries.
The problem is maintaining the order of the elements. Once I put the entries in the hashMap, the order will vanish.
There's nothing making the array vanish. Just iterate over the array, checking whether the value in the map is greater than one.
Just count elements and check if the total count of current element is greater than one.
Code example (C++11):
#include <iostream>
#include <unordered_map>
#include <vector>
int main() {
std::vector<int> to_split = {9, 1, 2, 4, 1, 2, 2};
std::vector<int> unique, not_unique;
std::unordered_map<int, int> counter;
for (int elem : to_split) {
++counter[elem];
}
for (int elem : to_split) {
if (counter[elem] > 1) {
not_unique.push_back(elem);
} else {
unique.push_back(elem);
}
}
std::cout << "Unique: " << std::endl;
for (int elem : unique) {
std::cout << elem << " ";
}
std::cout << std::endl;
std::cout << "Not unique:" << std::endl;
for (int elem : not_unique) {
std::cout << elem << " ";
}
std::cout << std::endl;
return 0;
}
Output:
Unique:
9 4
Not unique:
1 2 1 2 2
So an easy way to do this is to first count the number of each element (can be done in O(n)), iterate over the counter and put all elements with count = 1 in a set (also in O(n)).
Now run through the original list and print all elements that are not in your set (also O(n)). So the solution will run in O(n) time and space.
And here is 2 line solution in python:
from collections import Counter
arr = [9,1,2,4,1,2,2]
unique = {k for k, v in Counter(arr).iteritems() if v == 1}
print [i for i in arr if i not in unique]
I would do it like this:
create a
HashMap count =new HashMap();
iterate your array store the array-value as key and the count of the value as value in the hashmap
iterate the array a second time and remove value from the array if count to the key is one.
Just brainstorming a bit, but I somehow have to think about how an unstable sorting algorithm can be made stable: decorate, sort, undecorate.
Given your input list, you iterate over it, adding the position of the item to a list in a map.
for (i = 0; i < length; i++) {
value = list[i]
map[value].append(i)
}
Then, remove all items with count 1, and reconstruct the list (which you can do, because you have the indices in the map).
Thinking about it further: why not just do 1 loop counting, and then another loop to construct the filtered list? Probably even has better performance, I think O(n). (1 iteration to do the counts, 1 iteration to re-construct the new list)
Similar to fedekau's approach, but not counting:
int[]numbers = {9,1,2,4,1,2,2};
int guessedDistinct = (int)(2 * Math.sqrt(numbers.length));
final Map<Number, Boolean>
seenBefore = new HashMap<>(guessedDistinct);
for (int i : numbers)
seenBefore.put(i, seenBefore.containsKey(i));
int[] out = Arrays.stream(numbers)
.filter(i -> seenBefore.getOrDefault(i, false))
.toArray();
System.out.println(Arrays.toString(out));
(or try to avoid "finding i twice" in filling seenBefore:
for (int i : numbers)
seenBefore.compute(i, (k, seen) -> null != seen);

Generating Permutations in Lexicographic Order vs Sorting?

I'm a little bit confused. How is the problem of generating permutations in Lexicographic Order any different from the problem of sorting? Can someone please explain it to me with an example? Thanks
These are two different things. There are N! permutations, but there is only one sorted order (the sorted permutation is the smallest lexicographically).
Here is an example of a sorted permutation:
brown fox quick
Here is a list of permutations in lexicographic order:
brown fox quick
brown quick fox
fox brown quick
fox quick brown
quick brown fox
quick fox brown
Here is a program in C++ to generate permutations in lexicographic order:
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
int main() {
vector<string> s;
s.push_back("quick");
s.push_back("brown");
s.push_back("fox");
sort(s.begin(), s.end());
do {
for(int i = 0 ; i != s.size() ; i++) {
cout << s[i] << " ";
}
cout << endl;
} while (next_permutation(s.begin(), s.end()));
return 0;
}
Permutations are not addressed in the problem of sorting.
One way that they could relate is if you generate Permutations that are not in lexicographic order then you sort to get it in lexicographical order. This however would require to have factorial space. Generation usually spits out one element at a time therefore not having to have all elements in memory.
There's a fairly easy way to generate the nth permutation in lexicographic order. The set of choices you make in selecting the permutation elements are: pick 1 of N, then 1 of N-1, then 1 of N-2, ... then 1 of 2, and finally there's just one left. Those choices, as index values into a running "what's left" list, can be looked at as a variable-base number.
You can develop the digits from right to left as d[1] = n%2, d[2] = (n/2)%3, d[3] = (n/6)%4, ... d[k] = (n/k!) % (k+1). The result has d[N-1]==0 for the first (N-1)! permutations, d[N-1]==1 for the next (N-1)!, and so on. You can see that these index values will be in lex. order. Then choose the symbols out of your sorted set (Any random-access collection will do if syms[0], syms[1], ... are in the order you want.)
Here's some code I whipped up for working on Project Euler problems. It just generates the index values, and allows for choosing permutations of k symbols out of n. The header file defaults k to -1, and the argument check code converts this to n and generates full length permutations. There's also a change of notation here: "index" is the number of the permutation ("n" above) and "n" is the set size ("N" above).
vector<int> pe_permutation::getperm(long long index, int n, int k)
{
if (n<0) throw invalid_argument("permutation order (n)");
if (k<0 || k>n)
{
if (k==-1)
k=n;
else throw invalid_argument("permutation size (k)");
}
vector<int> sset(n, 0); // generate initial selection set {0..n-1}
for (int i=1; i<n; ++i)
sset[i] = i;
// Initialize result to sset index values. These are "without replacement"
// index values into a vector that decreases in size as each result value
// is chosen.
vector<int> result(k,0);
long long r = index;
for (int m=n-k+1; m<=n; ++m)
{
result[n-m] = (int)(r % m);
r = (r / m);
}
// Choose values from selection set:
for (int i=0; i<k; ++i)
{
int j = result[i];
result[i] = sset[j];
sset.erase(sset.begin()+j);
}
return result;
} // getperm(long long, int, int)
import java.util.*;
public class Un{
public static void main(String args[]){
int[]x={1,2,3,4};
int b=0;int k=3;
while(b!=(1*2*3*4)){
int count=0;
while(count!=6){
for(int i=2;i>0;i--){
int temp=x[i];
x[i]=x[3];
x[3]=temp;
count++;
System.out.println(x[0]+""+x[1]+""+x[2]+""+x[3]);
}
}
b+=count;
int temp=x[0];
x[0]=x[k];
x[k]=temp;
k--;
}
}
}

Longest common SUBSTRING optimization

Can anybody help me with optimization of my LONGEST COMMON SUBSTRING problem? I must read really big files (up to 2 Gb), but i cant figure out which structure to use... In c++ there is no hash maps.. There is concurrent hash map in TBB but it is very complicated to use with this algorithm. I have this problem solved with **L matrix but it is greedy and cannot be used for large inputs. Matrix is full of zeros, and that can be eliminated by i.e. using map> and store only non-zeros but that is really slow and practicaly unusable. Speed is very important. Here is the code :
// L[i][j] will contain length of the longest substring
// ending by positions i in refSeq and j in otherSeq
size_t **L = new size_t*[refSeq.length()];
for(size_t i=0; i<refSeq.length();++i)
L[i] = new size_t[otherSeq.length()];
// iteration over the characters of the reference sequence
for(size_t i=0; i<refSeq.length();i++){
// iteration over the characters of the sequence to compare
for(size_t j=0; j<otherSeq.length();j++){
// if the characters are the same,
// increase the consecutive matching score from the previous cell
if(refSeq[i]==otherSeq[j]){
if(i==0 || j==0)
L[i][j]=1;
else
L[i][j] = L[i-1][j-1] + 1;
}
// or reset the matching score to 0
else
L[i][j]=0;
}
}
// output the matches for this sequence
// length must be at least minMatchLength
// and the longest possible.
for(size_t i=0; i<refSeq.length();i++){
for(size_t j=0; j<otherSeq.length();j++){
if(L[i][j]>=minMatchLength) {
//this sequence is part of a longer one
if(i+1<refSeq.length() && j+1<otherSeq.length() && L[i][j]<=L[i+1][j+1])
continue;
//this sequence is part of a longer one
if(i<refSeq.length() && j+1<otherSeq.length() && L[i][j]<=L[i][j+1])
continue;
//this sequence is part of a longer one
if(i+1<refSeq.length() && j<otherSeq.length() && L[i][j]<=L[i+1][j])
continue;
cout << i-L[i][j]+2 << " " << i+1 << " " << j-L[i][j]+2 << " " << j+1 << "\n";
// output the matching sequences for debugging :
//cout << refSeq.substr(i-L[i][j]+1,L[i][j]) << "\n";
//cout << otherSeq.substr(j-L[i][j]+1,L[i][j]) << "\n";
}
}
}
There is a Intel Contest about the same problem.
Maybe they will post some solutinons when it's over
http://software.intel.com/fr-fr/articles/AYC-early2012_home/

Resources