views:

240

answers:

4

I have a c++ source code that was written in linux/unix environment by some other author. It gives me errors when i compile it in windows vista environment. I am using Bloodshed Dev C++ v 4.9. please help.

#include <iostream.h>
#include <map>
#include <vector>
#include <string>
#include <string.h>
#include <strstream>
#include <unistd.h>
#include <stdlib.h>


using namespace std;

template <class T> class PrefixSpan {
private:
  vector < vector <T> >             transaction;
  vector < pair <T, unsigned int> > pattern;
  unsigned int minsup;
  unsigned int minpat;
  unsigned int maxpat;
  bool all;
  bool where;
  string delimiter;      
  bool verbose;
  ostream *os;

  void report (vector <pair <unsigned int, int> > &projected) 
  {
    if (minpat > pattern.size()) return;

    // print where & pattern
    if (where) { 
      *os << "<pattern>" << endl;

      // what:
      if (all) {
 *os << "<freq>" << pattern[pattern.size()-1].second << "</freq>" << endl;
 *os << "<what>";
 for (unsigned int i = 0; i < pattern.size(); i++) 
   *os << (i ? " " : "") << pattern[i].first;
      } else {
 *os << "<what>";
  for (unsigned int i = 0; i < pattern.size(); i++)
    *os << (i ? " " : "") << pattern[i].first 
        << delimiter << pattern[i].second;
      }

      *os << "</what>" << endl;

      // where
      *os << "<where>";
      for (unsigned int i = 0; i < projected.size(); i++) 
 *os << (i ? " " : "") << projected[i].first;
      *os << "</where>" << endl;

      *os << "</pattern>" << endl;

    } else {

      // print found pattern only
      if (all) {
  *os << pattern[pattern.size()-1].second;
  for (unsigned int i = 0; i < pattern.size(); i++)
    *os << " " << pattern[i].first;
      } else {
  for (unsigned int i = 0; i < pattern.size(); i++)
    *os << (i ? " " : "") << pattern[i].first
        << delimiter << pattern[i].second;
      }

      *os << endl;
    }
  }

  void project (vector <pair <unsigned int, int> > &projected)
  {
    if (all) report(projected);

    map <T, vector <pair <unsigned int, int> > > counter;

    for (unsigned int i = 0; i < projected.size(); i++) {
      int pos = projected[i].second;
      unsigned int id  = projected[i].first;
      unsigned int size = transaction[id].size();
      map <T, int> tmp;
      for (unsigned int j = pos + 1; j < size; j++) {
 T item = transaction[id][j];
 if (tmp.find (item) == tmp.end()) tmp[item] = j ;
      }

      for (map <T, int>::iterator k = tmp.begin(); k != tmp.end(); ++k) 
 counter[k->first].push_back (make_pair <unsigned int, int> (id, k->second));
    }

    for (map <T, vector <pair <unsigned int, int> > >::iterator l = counter.begin (); 
  l != counter.end (); ) {
      if (l->second.size() < minsup) {
 map <T, vector <pair <unsigned int, int> > >::iterator tmp = l;
 tmp = l;
 ++tmp;
 counter.erase (l);
 l = tmp;
      } else {
 ++l;
      }
    }

    if (! all && counter.size () == 0) {
      report (projected);
      return;
    }

    for (map <T, vector <pair <unsigned int, int> > >::iterator l = counter.begin (); 
  l != counter.end(); ++l) {
      if (pattern.size () < maxpat) {
  pattern.push_back (make_pair <T, unsigned int> (l->first, l->second.size()));
  project (l->second);
  pattern.erase (pattern.end());
      }
    }
  }

public:
  PrefixSpan (unsigned int _minsup = 1,
       unsigned int _minpat = 1,        
       unsigned int _maxpat = 0xffffffff,
       bool _all = false,
       bool _where = false,
       string _delimiter = "/",
       bool _verbose = false):
    minsup(_minsup), minpat (_minpat), maxpat (_maxpat), all(_all), 
    where(_where), delimiter (_delimiter),  verbose (_verbose) {};

  ~PrefixSpan () {};

  istream& read (istream &is) 
  {
    string line;
    vector <T> tmp;
    T item;
    while (getline (is, line)) {
       tmp.clear ();
       istrstream istrs ((char *)line.c_str());
       while (istrs >> item) tmp.push_back (item);
       transaction.push_back (tmp);
    }

    return is;
  }

  ostream& run (ostream &_os)
  {
    os = &_os;
    if (verbose) *os << transaction.size() << endl;
    vector <pair <unsigned int, int> > root;
    for (unsigned int i = 0; i < transaction.size(); i++) 
      root.push_back (make_pair (i, -1));
     project (root); 
    return *os;
  }

  void clear ()
  {
    transaction.clear ();
    pattern.clear ();
  }
};

int main (int argc, char **argv)
{
  extern char *optarg;
  unsigned int minsup = 1;
  unsigned int minpat = 1;
  unsigned int maxpat = 0xffffffff;
  bool all = false;
  bool where = false;
  string delimiter = "/";
  bool verbose = false;
  string type = "string"; 

  int opt;
  while ((opt = getopt(argc, argv, "awvt:M:m:L:d:")) != -1) {
    switch(opt) {
    case 'a':
      all = true;
      break;
    case 'w':
      where = true;
      break;
    case 'v':
      verbose = true;
      break;
    case 'm':
      minsup = atoi (optarg);
      break;
    case 'M':
      minpat = atoi (optarg);
      break;
    case 'L':
      maxpat = atoi (optarg);
      break;
    case 't':
      type = string (optarg); 
      break;
    case 'd':
      delimiter = string (optarg);
      break;
    default:
      cout << "Usage: " << argv[0] 
    << " [-m minsup] [-M minpat] [-L maxpat] [-a] [-w] [-v] [-t type] [-d delimiter] < data .." << endl;
      return -1;
    }
  }

  if (type == "int") { 
     PrefixSpan<unsigned int> prefixspan (minsup, minpat, maxpat, all, where, delimiter, verbose);
     prefixspan.read (cin);
     prefixspan.run  (cout);
  }else if (type == "short") {
     PrefixSpan<unsigned short> prefixspan (minsup, minpat, maxpat, all, where, delimiter, verbose);
     prefixspan.read (cin);
     prefixspan.run  (cout);
  } else if (type == "char") {
     PrefixSpan<unsigned char> prefixspan (minsup, minpat, maxpat, all, where, delimiter, verbose);
     prefixspan.read (cin);
     prefixspan.run  (cout);
  } else if (type == "string") {
     PrefixSpan<string> prefixspan (minsup, minpat, maxpat, all, where, delimiter, verbose);
     prefixspan.read (cin);
     prefixspan.run  (cout);
  } else { 
     cerr << "Unknown Item Type: " << type << " : choose from [string|int|short|char]" << endl;
     return -1;
  }

  return 0;
}
+5  A: 

You can get it working on Windows by removing the <unistd.h> include and eliminating your use of the getopt() function... you will have to parse the commandline manually or use boost::program_options.

The header <unistd.h> and the the getopt() function are both available on UNIX-compliant operating systems, but not available on Windows (which is flagrantly non-compliant). If you want to be able to compile without any source code changes, you might also try downloading and installing Cygwin, which attempts to provide a UNIX-compliant environment inside of Windows with a modicum of success (though it isn't perfect, by any means). Alternatively, in the future, you can use a cross-platform library such as Boost or Qt.

Manual Parsing
Based on your usage message, you could replace the while-loop with the following code:

int idx=1;
while ( idx < argc ){
    std::string arg(argv[idx]);
    if (arg == "-m"){
        //minsup 
        idx++;
        if (idx>argc){ 
           std::cerr<<"Option \""<<arg<<"\" requires parameter."<<std::endl;
           usage(argv[0]); // move usage message into a function
           std::exit(1);
        }
        minsup=atoi(argv[idx++]);
    }else if (arg == "-M"){
        //minpat
        idx++;
        if (idx>argc){ 
           std::cerr<<"Option \""<<arg<<"\" requires parameter."<<std::endl;
           usage(argv[0]); // move usage message into a function
           std::exit(1);
        }
        minpat=atoi(argv[idx++]);
    }else if (arg == "-L"){
        //maxpat
        idx++;
        if (idx>argc){ 
           std::cerr<<"Option \""<<arg<<"\" requires parameter."<<std::endl;
           usage(argv[0]); // move usage message into a function
           std::exit(1);
        }
        maxpat=atoi(argv[idx++]);
    }else if (arg == "-a"){
        all=true;
        idx++;
    }else if (arg == "-w"){
        where=true;
        idx++;
    }else if (arg == "-v"){
        verbose=true;
        idx++;
    }else if (arg == "-t"){
        //type
        idx++;
        if (idx>argc){ 
           std::cerr<<"Option \""<<arg<<"\" requires parameter."<<std::endl;
           usage(argv[0]); // move usage message into a function
           std::exit(1);
        }
        type=argv[idx++];
    }else if (arg == "-d"){
        idx++;
        if (idx>argc){ 
           std::cerr<<"Option \""<<arg<<"\" requires parameter."<<std::endl;
           usage(argv[0]); // move usage message into a function
           std::exit(1);
        }
        delimiter=argv[idx++];
    }else {
        usage();
        std::exit(1);
    }
}

Then add the following code somewhere before your main function:

void usage(const char* progname)
{
    std::cout << "Usage: " << progname << " [-m minsup] [-M minpat] [-L maxpat] [-a] [-w] [-v] [-t type] [-d delimiter]" < data .." << endl;
}

Note that this is slightly different from how getopt actually behaves (getopt would allow you to combine -awv together, whereas this parsing won't... but if that isn't important, then this should get the job done.

Michael Aaron Safyan
thanks Michael, i am trying to follow your instructions. But I have not worked in c++ much and was thinking that i might be able to compile it right away.
HTMZ
@HTMZ, if you want to compile without any changes, then your best bet is Cygwin.
Michael Aaron Safyan
@HTMZ, I have updated with code to parse manually.
Michael Aaron Safyan
DevCpp has built-in mingw32-gcc compiler and it has unistd.h in include folder, its not the case IMHO
S.Mark
+1 Hadn't noticed boost::program_options, looks like a useful library.
Paul Arnold
Windows is "flagrantly non-compliant" with the UNIX standard? Who'd have believed that?
MSalters
@MSalters, all other major OSs comply (or at least try to do so). Windows is the only one that doesn't even bother to conform with the Single UNIX Specification, or even IEEE Std 1003.1 "POSIX" (a subset of the Single UNIX Specification), for that matter. So, yes, it is a little surprising.
Michael Aaron Safyan
A: 

Probably the easiest approach is to install cygwin - this gives you a Linux-compatible environment on Windows and this then makes it a lot easier to compile Linux code.

Paul R
+1  A: 

Here we go, you've just got good compiler. mingw32-gcc compiler (which is DevCpp built-in compiler) just giving some error like this

error: dependent-name ` T::int' is parsed as a non-type, but instantiation yields a type

It does not take map <T, int>::iterator as a type because thats depends on Templates, you need to use typename keyword for dependent names

So, use typename map <T, int>::iterator

I have done test compiled here. there is source main.cpp file and compiled .exe file and a data file.

And looks like you got those codes from here

http://www.chasen.org/~taku/software/prefixspan/

its GPL v2, you might need to add those license to your code too.

Edit: Adding fixed codes for later reference

/*
 PrefixSpan: An efficient algorithm for sequential pattern mining

 $Id: prefixspan.cpp,v 1.8 2002/04/03 13:35:23 taku-ku Exp $;

 Copyright (C) 2002 Taku Kudo   All rights reserved.
 This is free software with ABSOLUTELY NO WARRANTY.

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 02111-1307, USA
*/

#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <string.h>
#include <strstream>
#include <unistd.h>
#include <stdlib.h>

using namespace std;

template <class T> class PrefixSpan {
private:
    vector < vector <T> >            transaction;
    vector < pair <T, unsigned int> > pattern;
    unsigned int minsup;
    unsigned int minpat;
    unsigned int maxpat;
    bool all;
    bool where;
    string delimiter;
    bool verbose;
    ostream *os;

void report (vector <pair <unsigned int, int> > &projected){
    if (minpat > pattern.size()) return;

    // print where & pattern
    if (where) {
        *os << "<pattern>" << endl;

        // what:
        if (all) {
            *os << "<freq>" << pattern[pattern.size()-1].second << "</freq>" << endl;
            *os << "<what>";
            for (unsigned int i = 0; i < pattern.size(); i++)
                *os << (i ? " " : "") << pattern[i].first;
            } else {
                *os << "<what>";
                 for (unsigned int i = 0; i < pattern.size(); i++)
                    *os << (i ? " " : "") << pattern[i].first << delimiter << pattern[i].second;
            }
            *os << "</what>" << endl;

        // where
        *os << "<where>";
        for (unsigned int i = 0; i < projected.size(); i++)
            *os << (i ? " " : "") << projected[i].first;
        *os << "</where>" << endl;
        *os << "</pattern>" << endl;
    } else {
        // print found pattern only
        if (all) {
             *os << pattern[pattern.size()-1].second;
             for (unsigned int i = 0; i < pattern.size(); i++)
                *os << " " << pattern[i].first;
            } else {
                 for (unsigned int i = 0; i < pattern.size(); i++)
                    *os << (i ? " " : "") << pattern[i].first << delimiter << pattern[i].second;
            }

        *os << endl;
    }
}

void project (vector <pair <unsigned int, int> > &projected){
    if (all) report(projected);

    map <T, vector <pair <unsigned int, int> > > counter;

    for (unsigned int i = 0; i < projected.size(); i++) {
        int pos = projected[i].second;
        unsigned int id = projected[i].first;
        unsigned int size = transaction[id].size();
        map <T, int> tmp;
        for (unsigned int j = pos + 1; j < size; j++) {
            T item = transaction[id][j];
            if (tmp.find (item) == tmp.end()) tmp[item] = j ;
        }

        for (typename map <T, int>::iterator k = tmp.begin(); k != tmp.end(); ++k)
            counter[k->first].push_back (make_pair <unsigned int, int> (id, k->second));
    }

    for (typename map <T, vector <pair <unsigned int, int> > >::iterator l = counter.begin ();
    l != counter.end (); ) {
        if (l->second.size() < minsup) {
            typename map <T, vector <pair <unsigned int, int> > >::iterator tmp = l;
            tmp = l;
            ++tmp;
            counter.erase (l);
            l = tmp;
        } else {
            ++l;
        }
    }

    if (! all && counter.size () == 0) {
        report (projected);
        return;
    }

    for (typename map <T, vector <pair <unsigned int, int> > >::iterator l = counter.begin ();
    l != counter.end(); ++l) {
        if (pattern.size () < maxpat) {
             pattern.push_back (make_pair <T, unsigned int> (l->first, l->second.size()));
             project (l->second);
             pattern.erase (pattern.end());
        }
    }
}

public:
    PrefixSpan (unsigned int _minsup = 1,
            unsigned int _minpat = 1,
            unsigned int _maxpat = 0xffffffff,
            bool _all = false,
            bool _where = false,
            string _delimiter = "/",
            bool _verbose = false):
    minsup(_minsup), minpat (_minpat), maxpat (_maxpat), all(_all),
    where(_where), delimiter (_delimiter),  verbose (_verbose) {};

    ~PrefixSpan () {};

    istream& read (istream &is){
        string line;
        vector <T> tmp;
        T item;
        while (getline (is, line)) {
            tmp.clear ();
            istrstream istrs ((char *)line.c_str());
            while (istrs >> item) tmp.push_back (item);
            transaction.push_back (tmp);
        }

        return is;
    }

    ostream& run (ostream &_os){
        os = &_os;
        if (verbose) *os << transaction.size() << endl;
        vector <pair <unsigned int, int> > root;
        for (unsigned int i = 0; i < transaction.size(); i++)
            root.push_back (make_pair (i, -1));
         project (root);
        return *os;
    }

    void clear (){
        transaction.clear ();
        pattern.clear ();
    }
};

int main (int argc, char **argv){
    extern char *optarg;
    unsigned int minsup = 1;
    unsigned int minpat = 1;
    unsigned int maxpat = 0xffffffff;
    bool all = false;
    bool where = false;
    string delimiter = "/";
    bool verbose = false;
    string type = "string";

    int opt;
    while ((opt = getopt(argc, argv, "awvt:M:m:L:d:")) != -1){
        switch(opt) {
        case 'a':
            all = true;
            break;
        case 'w':
            where = true;
            break;
        case 'v':
            verbose = true;
            break;
        case 'm':
            minsup = atoi (optarg);
            break;
        case 'M':
            minpat = atoi (optarg);
            break;
        case 'L':
            maxpat = atoi (optarg);
            break;
        case 't':
            type = string (optarg);
            break;
        case 'd':
            delimiter = string (optarg);
            break;
        default:
            cout << "Usage: " << argv[0]
            << " [-m minsup] [-M minpat] [-L maxpat] [-a] [-w] [-v] [-t type] [-d delimiter] < data .." << endl;
            return -1;
        }
    }

    if (type == "int") {
         PrefixSpan<unsigned int> prefixspan (minsup, minpat, maxpat, all, where, delimiter, verbose);
         prefixspan.read (cin);
         prefixspan.run (cout);
    }else if (type == "short") {
         PrefixSpan<unsigned short> prefixspan (minsup, minpat, maxpat, all, where, delimiter, verbose);
         prefixspan.read (cin);
         prefixspan.run (cout);
    } else if (type == "char") {
         PrefixSpan<unsigned char> prefixspan (minsup, minpat, maxpat, all, where, delimiter, verbose);
         prefixspan.read (cin);
         prefixspan.run (cout);
    } else if (type == "string") {
         PrefixSpan<string> prefixspan (minsup, minpat, maxpat, all, where, delimiter, verbose);
         prefixspan.read (cin);
         prefixspan.run (cout);
    } else {
        cerr << "Unknown Item Type: " << type << " : choose from [string|int|short|char]" << endl;
        return -1;
    }

    return 0;
}
S.Mark
@S.Mark, thanks alot. Yes, the code is from http://www.chasen.org/~taku/software/prefixspan/. I only omitted the license details in an attempt to post the question clearly; should have cited the author. Thanks for mentioning.
HTMZ
You're welcome @HTMZ!
S.Mark
A: 

The code compiles for me using mingw 4.4.1 (no need for cygwin) if I replace occurrences of:

map <T,...

with

typename map <T, ...

as others have suggested, and replace:

<iostream.h>

with:

<iostream>

Can I also observe that DevC++ is no longer being developed, and is buggy as hell - you should consider switching to a better alternative, such as Code::Blocks.

anon
@Neil, btw, DevC++ is changed to wxDevC++, and its has very good progress.
S.Mark