Cout data in "KWIC" format

Hello, I wrote a method that successfully print words to console (reading from a BST and a list in the BST node).

For example, I am currently printing the following to console:
zwordBwordDword+Aword+EwordFwordWwordTwordXword
zword+Bword+DwordAwordEwordFwordWword
zwordBword+Dword+AwordEwordFwordWwordTword

Request: I need to print the data above (the words that appear between "+") always centralized. For example this would the desired output (the word between "+" should be aligned):
1
2
3
zwordBwordDword+Aword+EwordFwordWwordTwordXword
                   zword+Bword+DwordAwordEwordFwordWword
         ZwordBword+Dword+AwordEwordFwordWwordTword

QUESTION: Can you kindly suggest how I should approach the change needed to accomplish it? The code I am using to print to console is below:

1
2
3
4
5
6
7
8
9
10
11
 void List::display() const
{
	//Display all node value to console
	Node* cur_node = head;
	while (cur_node != nullptr)
	{
		cout << cur_node->word;
		cur_node = cur_node->next;
	}
	 
}
Last edited on
So is each line a node in your BST, and the words on that line in a list?

Are there always 3 words?
Where do the plus signs come from (in your code).

> Request: I need to print the data above (the words that appear between "+") always centralized
Do you assume a particular screen width (say 80 chars), or are you expected to somehow figure out how wide your console is (this is non-trivial and implementation specific).

Your 3-line output, is that being formatted correctly on the forum?
Note that what you see when editing won't be the same spacing after you hit post, because the spacing will be monospaced. If you're having trouble, I suggest writing the text in a monospace text editor and then pasting the code inside [code] or [output] tags.
Last edited on
I noticed it is not being formatted on the forum. The KWIC format is demonstrated here:
https://en.wikipedia.org/wiki/Key_Word_in_Context

Note:I could have up to 5 words before the word centralized (that is, word between "+") and 5 words maximum after that centralized word. Here is the BST code in which I print the "+" sign:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
//===================BST.cpp code==========================
#include "BST.h"
#include <iostream>
#include <string>

using namespace std;

BST::BST()
{
	root = nullptr;
	
}

BST::Node::Node()
{
	leftChild = nullptr;
	rightChild = nullptr;
}
void BST::addData(std::string key, List * before, List * after)
{
	//If there is no root (it means, first time adding nodes)
	if (root != nullptr) {
		
		addData(key, before, after, root);

	} else {
		
		root = new Node;
		root->key = key;
		root->leftChild = nullptr;
		root->rightChild = nullptr;
		root->before.push_back(before);
		root->after.push_back(after);
 
	}
	
}

void BST::addData(std::string key, List* before, List* after, Node* leaf)
{

	if (key < leaf->key)
	{
		if (leaf->leftChild != nullptr)
		{
			addData(key, before, after, leaf->leftChild);
		}
		else
		{
			leaf->leftChild = new Node;
			leaf->leftChild->key = key;
			leaf->leftChild->leftChild = nullptr;
			leaf->leftChild->rightChild = nullptr;
			leaf->leftChild->before.push_back(before);
			leaf->leftChild->after.push_back(after);
		}
	}
	else if (key > leaf->key)
	{
		if (leaf->rightChild != nullptr)
		{
			addData(key, before, after, leaf->rightChild);

		}
		else
		{
			leaf->rightChild = new Node;
			leaf->rightChild->key = key;
			leaf->rightChild->rightChild = nullptr;
			leaf->rightChild->leftChild = nullptr;
			leaf->rightChild->before.push_back(before);
			leaf->rightChild->after.push_back(after);
		}
	}
	// add condition if key added is duplicate, add code here to address before,after content.
	else
	{
		leaf->before.push_back(before);
		leaf->after.push_back(after);
	}

}
void BST::display(Node* node) const 
{
	//check if it is null
	if (node == nullptr)
	{
		return;
	}
	//printing the current node (BST node), key and value

	display(node->leftChild);
	cout << " \n";
	
	for (int i = 0; i < node->after.size(); i++)
	{
		node->before[i]->display();
		cout << "+" << node->key << "+" ;
		node->after[i]->display();
		
	}
	cout << " \n";
	display(node->rightChild);
		
		
}

void BST::display() const
{
	display(root);
}
//====list.cpp below contains the lists for the up to 5 words before and after.=
#include "List.h"
#include <iostream>
#include <string>

using namespace std;

List::List()
{
	head = nullptr;
	tail = nullptr;
}
List::~List()
{

}

void List::add(string word)
{
	//If list is empty
	if (head == nullptr)
	{
		head = new Node;
		head->word = word;

		head->next = nullptr;
		tail = head;
	}
	else
	{
		//Case list is not empty
		
		Node * other_node = new Node;
		other_node->word = word;
		other_node->next = nullptr;
		tail->next = other_node;
		tail = other_node;
	}

}

void List::clear()
{
	//Clear all nodes from the list

	//If list is empty, nothing to do.
	if (isEmpty() == true)
	{
		return;
	}
	//Traverse until node element is not the only element 
	while (head->next != nullptr)
	{
		//assign head the next node element
		Node * tmp = head;
		head = head->next;
		//delete the old head
		delete tmp;
		
	}
	//Delete current node
	delete head;
	head = nullptr;
}

void List::display() const
{
	//Display all node value to console
	Node* cur_node = head;
	while (cur_node != nullptr)
	{
		cout << cur_node->word;
		cur_node = cur_node->next;
	}
	 
}

bool List::isEmpty() const
{
	return head == nullptr;
}  
===main.cpp==========================
#include "BST.h"
#include "List.h"
#include <iostream>
#include <vector>
#include <fstream>
#include <set>
#include <algorithm>

using namespace std;

int main()
{
	BST mytree;
	vector<string> read;
	ifstream myfile;
	myfile.open("inputkey.txt");
	string myread;
	
	while (!myfile.eof())
	{
		myfile >> myread;
		if (myfile.fail())
		{
			break;
		}
		string realword = "";
		for (int i = 0; i < myread.size(); i++)
		{
			if (isalpha(myread[i]))
			{
				realword += myread[i];
				cout << "Yes it is alpha = " << myread[i] << endl;
				
			}

		}
		read.push_back(realword);
	}
	myfile.close();

	myfile.open("stopwords.txt");
	set<string> myset;
	while (!myfile.eof())
	{
		myfile >> myread;
		if (myfile.fail())
		{
			break;
		}

		myset.insert(myread);
		
	}
	myfile.close();


	for (int i = 0; i < read.size(); i++)
	{

		//Create before and after lists
		List* listbefore = new List;
		List* listafter = new List;


		for (int j = max(0, i - 6); j < i; j++)
		{
			listbefore->add(read[j]);

		}

		for (int j = i + 1; j < i + 7 && j < read.size(); j++)
		{
			listafter->add(read[j]);

		}

		mytree.addData(read[i], listbefore, listafter);
	}

	mytree.display();
}
Last edited on
You can edit your first post to fix the formatting. (Again, I suggest doing the formatting in a monospace editor like Notepad, and then copy+pasting it here.)

Place the formatted text between [code] or [output] tags.

The fact that you're using a BST to generate the output really is an implementation detail. What matters is that you have some sort of sequence of words, and you're trying to format them.

I think I see what you're saying now. You want each word between the 2x ++'s to be left-justified and aligned vertically?
Last edited on
Is this what you are trying to do?
zwordBwordDword+Aword+EwordFwordWwordTwordXword
          zword+Bword+DwordAwordEwordFwordWword
     zwordBword+Dword+AwordEwordFwordWwordTword

If so, I might:

1. turn each line of output into a string. Store each line of output in a container.

2. find the greatest distance (number of characters) between the start of a string and the location of the first +. Save that value.

3. In a loop examine each string to see if the first + is at a shorter distance. The difference between the current distance and the greatest distance is the number of spaces to pad the output before doing the string output.

If that isn't what you are trying to do, then ignore what I said.
Thanks Furry. You got it. Let me try to implement it...
Topic archived. No new replies allowed.