Decision Tree - Google Code Jam 2009 Round 1B A題

是一道水題,其最重要的部分在於字符串處理建立樹。


代碼如下: 

#include"stdafx.h"
#include<iostream>
#include<string>
#include<stdio.h>
#include <iomanip>
#include<set>

using namespace std;
#define LEFTBRACKET '('
#define RIGHTBRACKET ')'
const int MAX = 1000;


class Node{
public:
	Node *left, *right;
	string feature;
	bool leaf;
	double weight;
	
	Node() {
		left = right = 0;
		leaf = true;
		weight = 0.0;
	}
	void set(double, bool, string);
	void set(double);
};

class Stack{
private:
	Node *a[MAX];
	int top;
public:
	Stack():top(-1){}
	void Push(Node *);
	void Pop();
	Node *Top();
	bool IsEmpty();
};


typedef Node* Tree;

Tree ConstructDecisionTree(int lines);
double ComputeValue(Tree tr, set<string> s);
void DestroyTree(Tree tr);

int main() {
	freopen("../A-large-practice.in", "r", stdin);
	//freopen("../A-small-practice.in", "r", stdin);
	//freopen("Input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	int casenum;
	int tline, anims; 
	string s;
	cin>>casenum;
	for(int p = 0; p < casenum; p++) {
		cin>>tline;
		Tree tr = ConstructDecisionTree(tline); //建樹的過程應該是調試好了。
		cout<<"Case #"<<(p + 1)<<":"<<endl;
		cin>>anims;
		cin.get();
		for(int i = 0; i < anims; i++) {	
			int temp;
			set<string>sets;
			cin>>s>>temp; //Animal name and feature num
			//getline(cin, s);
			for(int i = 0; i < temp; i++) {
				cin>>s;
				sets.insert(s);
			}

			double ret = ComputeValue(tr, sets);
			//cout<<setprecision(7)<<ret<<endl;
			printf("%.7f\n", ret);
		}
		DestroyTree(tr);
	}
}

Tree ConstructDecisionTree(int lines) {
	Node *curNode, *root;
	double weight;
	char temp;
	string feature;
	Stack s;
	for(int i = 0; i < lines; i++) {
		do {
			cin>>temp;
		}while(temp != LEFTBRACKET && temp != RIGHTBRACKET); //May cause infinite loop
		if(temp == RIGHTBRACKET) {s.Pop(); continue;}
		//We encouter a leftbracket

		cin>>weight; //we get the weight
		cin>>feature; //Try to get the feature
		cin.get();
		curNode = new Node();
		if(s.IsEmpty()){ 
			root = curNode;
		}else {
			if(s.Top()->left == 0) s.Top()->left = curNode;
			else s.Top()->right = curNode;
		}

		s.Push(curNode);

		//if feature contains too many ")"
		if(feature[0] != RIGHTBRACKET) {
			curNode->set(weight, false, feature);
		}else {
			//there are feature.size() ‘)’
			for(int k = 0; k < feature.size(); k++) s.Pop();
			curNode->set(weight);
		}	
	}
	return root;
}

double ComputeValue(Tree tr, set<string> s) {
	//s中查找字符串
	double pro = 1.0f;
	Node *p = tr;
	//set<string>::iterator it;

	while(true) {
		pro *= p->weight;
		if(p->leaf) break;
		else {
			/*
			if(s.find(p->feature) != string::npos) p = p->left;
			else p = p->right;
			假設爲s爲 sdd, ddd, sdsdfd,
			那麼當p->feature爲dd時候,會顯示爲正確
			要考慮越界的情形,還有其他的問題。 果然是這個問題
			*/
			if(s.find(p->feature) != s.end() ) p = p->left;
			else p = p->right;
			
			
		} 
	}
	
	
	return pro;

}

void DestroyTree(Tree tr) {
	if(tr == 0) return;
	DestroyTree(tr->right);
	DestroyTree(tr->left);
	delete tr;
}


//字符串處理方面太弱了,一定得補上
void Node::set(double w, bool l, string fe){
	weight = w;
	leaf = l;
	feature = fe;
}

void Node::set(double w) {
	weight = w;
}
void Stack::Push(Node * v) {
	a[++top] = v;
}

void Stack::Pop() {
	--top;
}
Node* Stack::Top() {
	return a[top];
}

bool Stack::IsEmpty() {
	return top == -1;
}


總結: 

感覺自己還是不大懂得用C++,事實上使用Python做文本處理是更好的選擇。 決定最近去掌握一下Python和Lisp。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章