The output of the vector that you helped me make is a little hard to read.
Can you help me make it a little more readable like:
Input:
Enter number of different sizes: 5
and the inputs are :
35 x 2.36
23 x 1.23
12 x 4.23
16 x 8.25
15 x 2.89
and the output is a long list like:
Bar 1: 8.250 2.890
Bar 2: 8.250 2.890
Bar 3: 8.250 2.890
Bar 4: 8.250 2.890
Bar 5: 8.250 2.890
Bar 6: 8.250 2.890
Bar 7: 8.250 2.890
Bar 8: 8.250 2.890
Bar 9: 8.250 2.890
Bar 10: 8.250 2.890
Bar 11: 8.250 2.890
Bar 12: 8.250 2.890
Bar 13: 8.250 2.890
Bar 14: 8.250 2.890
Bar 15: 8.250 2.890
Bar 16: 8.250 2.890
Bar 17: 8.250 2.890
Bar 18 8.250 2.360 1.230 2.360
Bar 19: 4.230 4.230 2.360
Bar 20: 4.230 4.230 2.360
Bar 21: 4.230 4.230 2.360
Bar 22: 4.230 4.230 2.360
Bar 23: 4.230 4.230 2.360
Bar 24: 4.230 4.230 2.360 and so on

So instead of this if I could say.
1. You cut 17 bars by 8.250 and 2.890
2. You cut 1 bar 8.250 2.360 1.230 2.360
3. You cut 6 bars 4.230 4.230 2.360
Because usually you have hundreds of measures and an output like that is very unreadable.
Thank you

#include <iostream>
#include <iomanip>
#include <vector>
#include <iterator>
#include <algorithm>
#include <numeric>
/* Get the number of different lengths from the user */

struct Cut{
    unsigned number;
	double length;
};


int main () {
	
std::vector< Cut > allCuts;
Cut currentCut;
unsigned numberOfSizes;
std::cout << "Enter number of different sizes: ";
std::cin >> numberOfSizes;
 
/* Now get the actual numbers and lengths from the user */
for(unsigned i = 0; i < numberOfSizes; ++i){
	//currentCut = new Cut;
    std::cout << "Enter new cut: <number> <length>" << std::endl;
	std::cin >> currentCut.number >> currentCut.length;
   /* Check that the length is sensible */
    if((currentCut.length <= 0) || (currentCut.length > 12)){
        std::cerr << "Error length must be in the range (0,12]" << std::endl;
        --i;
    }
    else
        allCuts.push_back(currentCut);
}
 
/* Now put all the cuts into a single large vector */
std::vector< double > lengths;
for(unsigned i = 0; i < allCuts.size(); ++i){
    for(unsigned j = 0; j < allCuts[i].number; ++j)
        lengths.push_back(allCuts[i].length);
}
 
/* Sort the vector */
std::sort(lengths.begin(), lengths.end());
 
/* Make a place to put the lengths to cut from each bar */
const unsigned NEW_BAR_LENGTH = 12;
std::vector< std::vector< double > >bars;
std::vector< double > currentBar;
double remainingLength = NEW_BAR_LENGTH;
 
/* Now keep going through the lengths vector until all the cuts are accounted for */
while(lengths.size() > 0){
    /* start at the longest length that needs to be cut ... */
    std::vector< double >::iterator it = lengths.end() - 1;
    /* Go until the smallest length that's needed is reached */
    while(it >= lengths.begin()){
        /* Check if the current length will fit */
        if(*it < remainingLength){ /* If it will... */
            /* ... Add it to the current bar and remove it from the list to be fitted */
            currentBar.push_back(*it);
            /* Update the amount of the bar remaining */
            remainingLength -= *it;
            /* Remove the current element from the lengths vector */
           lengths.erase(it);
        }
        /* Check that we didn't just remove the last element */
        if(lengths.size() > 0){
            /* length[0] is the shortest length cut that we still need to get
               if this is more than the remaining amount of the current bar,
               then we should finish this bar and start a new one, check for
               this now */
            if(lengths[0] > remainingLength){
                /* Reset the remaining length */
                remainingLength = NEW_BAR_LENGTH;
                /* Add this completed bar to the vector of bars */
                bars.push_back(currentBar);
                /* Clear the current bar */
                currentBar.clear();
                /* Exit this loop and start on the new bar */
                break;
            }
        }
        --it;
    }
}

double totalWaste = 0.0;
for(unsigned i = 0; i < bars.size(); ++i){
    std::cout << "Bar " << std::setw(2) << i + 1 << ":\t";
    for(unsigned j = 0; j < bars[i].size(); ++j)
        std::cout << std::setprecision(3) << std::fixed << bars[i][j] << " ";
    std::cout << std::endl;
    std::partial_sum(bars[i].begin(), bars[i].end(), bars[i].begin());
    totalWaste += NEW_BAR_LENGTH - bars[i].back();
}
 
/* Print a summary */
std::cout << "===============================" << std::endl;
std::cout << "Bars used:\t" << bars.size() << std::endl;
std::cout << "Total waste:\t" << totalWaste << " m" << std::endl;
std::cout << "Waste/Bar:\t" << totalWaste/bars.size() << " m" << std::endl;
std::cout << "===============================" << std::endl;
system("pause");
return 0;
}

Edited 5 Years Ago by eduard77: n/a

OK, you probably shouldn't aim a forum question at a particular user, since that user may

  1. Not be checking the forum that week
  2. Not know the answer to your question.

Better to make a post with a title that describes you problem, such as "Count identical vectors" or something like that.

As for your problem, the simplest way to do it would be to use std::unique() to find the number of different types of bar to cut, and then use std::count() to find the number of each bar:

/* Find the number of different types of bar to cut */
std::vector< std::vector< double > > uniqueBars(allBars.size());
std::vector< std::vector< double > > it = std::unique_copy(allBars.begin(), allBars.end(), uniqueBars.begin());
uniqueBars.resize(it - uniqueBars.begin());

/* Count how many of each type we need */
std::vector< unsigned > numbers(uniqueBars.size());
for(unsigned i = 0; i < numbers.size(); ++i)
    numbers[i] = std::count(uniqueBars.begin(), uniqueBars.end(), uniqueBars[i]);

Some warnings:

  1. I haven't tested this at all, just wrote it in here
  2. std::unique only counts the consecutive elements that are equal, so this isn't very robust. You would have to write a new version of unique() to do this properly, but I'll leave that up to you!

A better way to do it might be with a combination of std::stringstream and std::map

This question has already been answered. Start a new discussion instead.