如何将一个while循环与for循环结合起来?

时间:2018-03-16 16:06:11

标签: c++ for-loop while-loop

我试图按照我的指示将这两个循环组合在一起,但我无法弄清楚我应该怎么做这样的事情。因为我在for循环中的计数器i不能进入循环条件。我的老师希望程序只做一个循环。提前致谢。代码基本上通过一个txt文件运行,并且应该首先为数组赋值,在for循环中我将它分配给一个指针。

这部分我遇到了问题:

void fillArr(vector <student> &arr, vector <student *> &ptrels){
    student temp;

    ifstream inFile ("index.txt");
    while (!inFile.eof()) {
        inFile >> temp.fName >> temp.Lname >> temp.gpa >> temp.id >> temp.email;
        arr.push_back(temp);
    }
    for (unsigned i = 0; i < arr.size(); i++ ){
        ptrels.push_back(&arr[i]);
    }

//    combine the two above loops
}

以下是整个代码:

> #include <string>
> #include <cstdio>
> #include <iostream>
> #include <vector>
> #include <fstream>
> #include <sstream> using namespace std;
> 
> struct student {
>     string fName, Lname, email, id;
>     double gpa; } ;
> 
> void input(); void fillArr(vector <student> &arr, vector <student *>
> &ptrels); void printFile(vector <student *> pointarray); void
> sortFile(vector <student> &arr, vector <student *> &pointarray);
> 
> int main() {
>     vector <student> elements;
>     vector <student *> ptrels;
>     
>     ifstream inFile;
>     inFile.open("index.txt");
>     
>     int answer;
>     fillArr(elements, ptrels);
>     cout << "Please select:" << endl
>     << "1 = Select All" << endl
>     << "2 = Order A-Z by Name"<<endl
>     << "3 = To exit"<< endl;
>     cin >> answer ;
>     if (answer == 1){
>         printFile(ptrels);
>         main();
>     }
>     if (answer ==2){
>         sortFile(elements, ptrels);
>         printFile(ptrels);
>         main();
>     }
>     if (answer ==3){
>         inFile.close();
>         exit(0);
>     }
>     else {
>         cout << "Invalid Try Again:"<< endl;
>         main();
>     }
>     return 0; }
> 
> void fillArr(vector <student> &arr, vector <student *> &ptrels){
>     student temp;
> 
>     ifstream inFile ("index.txt");
>     while (!inFile.eof()) {
>         inFile >> temp.fName >> temp.Lname >> temp.gpa >> temp.id >> temp.email;
>         arr.push_back(temp);
>     }
>     for (unsigned i = 0; i < arr.size(); i++ ){
>         ptrels.push_back(&arr[i]);
>     }
> 
> //    combine the two above loops }
> 
> 
> 
> void printFile(vector <student *> pointarray){
>     for (unsigned j = 0; j < pointarray.size(); j++){
>         cout << pointarray[j] -> fName << "    ";
>         cout << pointarray[j] -> Lname<< "    ";
>         cout << pointarray[j] -> gpa << "    ";
>         cout << pointarray[j] -> id << "    ";
>         cout << pointarray[j] -> email << "    ";
>         cout << endl;
>     } }
> 
> //swap the elements by pointer. you are swaping the record not the
> pointers. // only sorting by firstname, sort by all 5 void
> sortFile(vector <student> &arr, vector <student *> &pointarray){
>     for(unsigned i = 0; i < arr.size(); ++i){
>         for(unsigned j = i + 1; j < arr.size(); ++j) {
>             if(arr[i].fName > pointarray[j] -> fName) {
>                 swap(arr[i].fName,pointarray[j] ->fName);
>                 swap(arr[i].Lname,pointarray[j] ->Lname);
>                 swap(arr[i].gpa,pointarray[j] ->gpa);
>                 swap(arr[i].id,pointarray[j] ->id);
>                 swap(arr[i].email,pointarray[j] ->email);
>             }
>         }
>     } }

我也知道我应该在另一个问题中提出这个问题,但她也希望我做排序,这是排序所有值的最后一个函数sortFile,而不仅仅是firstName。再加上她讨厌交换功能,寻找替代品。任何提示将不胜感激。

3 个答案:

答案 0 :(得分:3)

天真的解决方案可能会将两个循环折叠成以下内容:

arr.empty()

假设arr.push_back(temp)是这个函数的前提条件(如果它不是,那么语义就会被破坏),这几乎可以做同样的事情。

几乎。

麻烦的是,每个arr可能会导致ptrels的扩展,使到目前为止您在arr中放入的所有指针无效。原始解决方案使用了第二个循环,这样您就可以在开始乱搞指针之前知道reserve已完成并进行了拂去。

我们仍然可以使用单循环解决方案,只要我们阻止向量中"index.txt"空间的重新分配。要做到这一点,您需要事先知道需要多少元素。为此,您需要使用{{1}}两次,然后再返回两个循环。

所以,基本上,你不能做到这一点。

真正的解决方案是拒绝要求。希望这是您的老师希望您报告的内容。我无法想到任何真实世界的用例,用于索引&#34;无论如何,在这样一个简单的情况下矢量。

另外,https://docs.branch.io/pages/apps/api/#link-read

答案 1 :(得分:1)

所以你发布了整个代码;解决方案绝对是完全不需要指针向量。

通过尝试按照你的方式处理2个向量,你的排序功能会更加困难;并且你的from twisted.internet import reactor, defer from scrapy.crawler import CrawlerRunner from scrapy.utils.log import configure_logging from scrapers.scrapy_new_users.helpers.dataAggregator import DataAggregator class MySpider1(scrapy.Spider): # Your first spider definition ... class MySpider2(scrapy.Spider): # Your second spider definition ... configure_logging() runner = CrawlerRunner() @defer.inlineCallbacks def crawl(): yield runner.crawl(MySpider1) yield runner.crawl(MySpider2) reactor.stop() crawl() reactor.run() data_aggregator = DataAggregator() data_aggregator.parse() 使用指针并不比使用向量引用更简单。

我不知道为什么你首先会有这个指针向量;除了有时他们习惯于尝试对组进行排序而不改变原始组的顺序。因为你确实改变了顺序,所以它是痛苦的载体。

摆脱它;让生活变得简单。

除了: 您的printFile()可以使用std :: sort,不仅更快,而且更容易阅读。

答案 2 :(得分:0)

C ++ 17代码(我将sort函数体留空,以便为作业留下一些事情,我认为那部分是主要的东西™):

// Source encoding: utf-8 with BOM ∩
#include <string>               // std::(string)
#include <iostream>             // std::(cout, cerr)
#include <optional>             // std::(optional)
#include <utility>              // std::(move)
#include <vector>               // std::(vector)
#include <fstream>              // std::(ifstream)
#include <sstream>              // std::(istringstream)
#include <stdexcept>            // std::(exception, runtime_error)
using namespace std;

auto hopefully( bool const e ) -> bool { return e; }
[[noreturn]] auto fail( string const& s ) -> bool { throw runtime_error( s ); }

auto optional_line_from( istream& stream )
    -> optional<string>
{
    string result;
    return getline( stream, result )? result : optional<string>{};
}

struct Student_info
{
    string first_name;
    string last_name;
    double gpa;
    string id;
    string email;
};

// Originally
// void fillArr(vector <Student_info> &arr, vector <Student_info *> &ptrels):

auto data_from( string const& filename )
    -> vector<Student_info>
{
    ifstream in_file{ "index.txt" };
    hopefully( not in_file.fail() )
        or fail( "Failed to open “index.txt” for reading." );

    vector<Student_info> result;
    while( optional<string> line = optional_line_from( in_file ) )
    {
        Student_info temp;
        istringstream items{ *line };
        items >> temp.first_name >> temp.last_name >> temp.gpa >> temp.id >> temp.email;
        hopefully( not items.fail() )
            or fail( "Failed to parse input line: “" + *line + "”." );
        result.push_back( move( temp) );
    }
    return result;
}

auto operator<<( ostream& stream, Student_info const& item )
    -> ostream&
{
    stream
        << item.first_name << "    "
        << item.last_name<< "    "
        << item.gpa << "    "
        << item.id << "    "
        << item.email;
    return stream;
}

// Originally
// void printFile(vector <student *> pointarray):

void print( vector<Student_info const*> const& pointers )
{
    for( auto const p : pointers ) { cout << *p << endl; }
}

// Originally
// void sortFile(vector <student> &arr, vector <student *> &pointarray):

void sort( vector<Student_info const*>& pointarray )
{
    // TODO:
    // Using std::sort is a good idea, if you're allowed to do that.
    // std::tuple instances can be lexicographically compared with `<`, and
    // `std::tie` produces a tuple. That's great for the current job.
}

// Originally
// int main():

void cpp_main()
{
    vector<Student_info> const data = data_from( "index.txt" );

    vector<Student_info const*> pointers;
    for( Student_info const& item : data ) { pointers.push_back( &item ); }

    for( ;; )
    {
        cout << "Please select\n"
             << "1 = Select All\n"
             << "2 = Order A-Z by Name\n"
             << "3 = To exit"
             << endl;
        try
        {
            switch( stoi( *optional_line_from( cin ) ) )
            {
                case 1:
                {
                    print( pointers );
                    break;
                }
                case 2:
                {
                    sort( pointers );
                    print( pointers );
                    break;
                }
                case 3:
                {
                    return;
                }
                default:
                {
                    fail( "" );
                }
            }
        }
        catch( ... )
        {
            // Avoid infinite loop on input failure:
            if( cin.fail() )
            {
                fail( "Failed reading standard input." );
            }
            cout << "Invalid Try Again:" << endl;
        }
    }
}

auto main()
    -> int
{
    try
    {
        cpp_main();
        return EXIT_SUCCESS;
    }
    catch( exception const& x ) 
    {
        cerr << "!" << x.what() << endl;
    }
    return EXIT_FAILURE;
}