Avatar billede raiser Nybegynder
26. december 2005 - 23:14 Der er 9 kommentarer

12*65^2-33 (opdeling?)

Hej,
jeg er stødt ind i et problem hvor jeg skal have 'c++' til at dele nogen ting op som brugeren indtaster. Så som "12*65^2-33" skal deles op i nogen forskellig variabler, array eller noget, så der kan udføres et regnestykke ud af det.
Går ud fra det er noget parsing det skal fikses med, men det er ikke min stærke  siden, endnu!:P
Så tænkte om der ikke var en der kunne hjælpe mig med det problem?:)
Avatar billede arne_v Ekspert
26. december 2005 - 23:16 #1
Det er absolut ikke triviel kode.

Jeg har noget kod eliggende her http://www.vajhoej.dk/arne/eksperten/EXPR/.

Det er gammel kode, men den virker.
Avatar billede raiser Nybegynder
26. december 2005 - 23:24 #2
Fors**** det ser indviklet ud - i forhold til min, ikke så udbredde viden om c++.
Det kan ikke gøre simplere?::)
Avatar billede arne_v Ekspert
26. december 2005 - 23:40 #3
Det kan muligvis gøres lidt nemmere.

Men du kan ikke gøre det med 15 linier ...
Avatar billede raiser Nybegynder
26. december 2005 - 23:47 #4
var godt klar over at det ikke var helt nemt. Men én mere pædagoisk metode, end bare at copy/paste og intet forstå og til sidst lærer lidt, men uden at forstå alt - må der da være:)
Avatar billede arne_v Ekspert
26. december 2005 - 23:50 #5
min kode kan opdeles i 3 trin

1) konvertering fra tekst streng til symbolsk form
2) konvertering fra infix til postfix notation
3) evaluering

Hvis du googler må du kunne finde mange andre eksempler på det samme.
Avatar billede raiser Nybegynder
26. december 2005 - 23:51 #6
Jeg vil prøve at kigge på det:P
Avatar billede bertelbrander Praktikant
27. december 2005 - 00:06 #7
Man kunne også kaste sig ud i noget i stil med:
#include <vector>
#include <string>
#include <iostream>
#include <sstream>

template <typename T>
bool FromString(T &aValue, const std::string &aStr)
{
  std::stringstream ss(aStr);
  return ss >> aValue;
}

class ElementBaseClass
{
public:
  enum ElementTypeEnum
  {
      NumberType,
      AddType = '+',
      SubType = '-'
  };

  ElementBaseClass(ElementTypeEnum aElementType) : ElementType(aElementType)
  {
  }
  ElementTypeEnum ElementType;
  virtual void Print(std::ostream& aOs) = 0;
  virtual ~ElementBaseClass(){}
};

class NumberElementClass : public ElementBaseClass
{
public:
  NumberElementClass(std::string& aStr) : ElementBaseClass(NumberType)
  {
      std::string::size_type pos = aStr.find_first_not_of("0123456789");
      if(pos == std::string::npos)
      {
        FromString(Number, aStr);
        aStr = "";
      }
      else
      {
        FromString(Number, aStr.substr(0, pos));
        aStr = aStr.substr(pos);
      }
  }
  virtual void Print(std::ostream& aOs)
  {
      aOs << Number;
  }
private:

  int Number;
};

class AddElementClass : public ElementBaseClass
{
public:
  AddElementClass(std::string& aStr) : ElementBaseClass(AddType)
  {
      aStr = aStr.substr(1);
  }
  virtual void Print(std::ostream& aOs)
  {
      aOs << '+';
  }
};

class SubElementClass : public ElementBaseClass
{
public:
  SubElementClass(std::string& aStr) : ElementBaseClass(SubType)
  {
      aStr = aStr.substr(1);
  }
  virtual void Print(std::ostream& aOs)
  {
      aOs << '+';
  }
};

bool Parse(std::vector<ElementBaseClass *>& aVector, std::string& aStr)
{
  while(!aStr.empty())
  {
      switch(aStr[0])
      {
      case '+':
        aVector.push_back(new AddElementClass(aStr));
        break;
      case '-':
        aVector.push_back(new SubElementClass(aStr));
        break;
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
        aVector.push_back(new NumberElementClass(aStr));
        break;
    case ' ':
        aStr = aStr.substr(1);
        break;
    default:
        return false;
      }
  }
  return true;
}

int main()
{
  std::vector<ElementBaseClass* > MyVector;
  std::string Str = "123 + 321 - 555";

  if(Parse(MyVector, Str))
  {
      std::vector<ElementBaseClass* >::iterator it;
      for(it = MyVector.begin(); it != MyVector.end(); ++it)
      {
        (*it)->Print(std::cout);
      }
      std::cout << std::endl;
  }
}
Avatar billede arne_v Ekspert
28. december 2005 - 22:54 #8
I forbindelse med et andet spørgsmål genfandt jeg lige den her
http://www.gnu.org/software/bison/manual/pdf/bison.pdf

I eksempel kapitlet er der noget tilsvarende ved hjælp af bison parser
generator.

Heller ikke helt simpelt men ihvertfald en anden tilgangsvinkel.
Avatar billede arne_v Ekspert
12. marts 2006 - 05:57 #9
Tid at få afsluttet her ?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester