Click here to Skip to main content
15,885,546 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
Hey everyone! i stuck here with a thing. I use this code in visual c++ to search a book by its author. I have used the approach of bubble sorting then binary searching.

Alright, now this is what i have. what i want to do now is to search a particular BOOK by its author without using the bubble sorting or binary searching method and instead search all the records one at a time, from start till the end for its author. I think the improved approach will make the coding a lot shorter than it is now

C++
//***************************************************************
//                   HEADER FILE USED IN PROJECT
//****************************************************************

#include<fstream> 
#include<conio.h>
#include<stdio.h>
#include<process.h>
#include<string.h>
#include<iomanip>
#include<iostream>


using namespace std;

class BOOK
{
public:
	char ID[6];
	char Content[50];
	char AUTHOR[20];
	char Book[20];
}  

void Copy(BOOK hd){ //  this function copies whole record
		strcpy(ID,(hd.ID)); //copy BOOK ki id
		strcpy(AUTHOR,(hd.AUTHOR)); // copy BOOK ka AUTHOR
		strcpy(Book,(hd.Book));
		strcpy(Content,(hd.Content));
}




	void SwapBOOK(BOOK &bk1, BOOK &bk2){ //swaps position of BOOK1 with BOOK2

	BOOK Temp;            

	Temp.Copy(bk1);  //BOOK1 ko temp main copy kiya
	bk1.Copy(bk2);   //BOOK2 ko BOOK1 main copy kiya (now BOOK2 has moved to the place of BOOK1)
	bk2.Copy(Temp);  //BOOK1 ko finalyy BOOK2 ki jaga per copy ker diya
}


//***************************************************************
//    	global declaration for stream object, object
//****************************************************************
fstream fp; // fstream provides an interface to read and write data from files as input/output streams.
ofstream ofp; // ofstream provides an interface to write data to files as output streams
//***************************************************************
//    	SORT AND SEARCH BY AUTHOR (START)
//****************************************************************



void SortByAUTHOR() // bubble sort
{
	for(int i=0; i< countBOOK-1; i++){
		for(int j=0; j <countBOOK-1; j++){
			if(strcmp(hd[j].AUTHOR,hd[j+1].AUTHOR)>0) 
				SwapBOOK(hd[j],hd[j+1]); // if above condition is satisfied, then call 'swapBOOK' function which is defined by us
		}
	}


}

//////////////////////////////////////////////////////////////////
void SearchBetweenIndex(int IndexA, int IndexB, char* AUTHOR)
{
	if(IndexA > IndexB){
		int temp;
		temp = IndexA;
		IndexA = IndexB;
		IndexB= temp;
	}

	for(int i = IndexA; i <= IndexB;i++){
		if(strcmp(hd[i].AUTHOR,AUTHOR)==0)
			hd[i].report();
	}

	getch();
}

/////////////////////////////////////////////////////////////////////

void ListByAUTHOR(char* AUTHOR){ //search by AUTHOR 	
	int PreviousIndex = 0; // first 

	int StartIndex =0 , EndIndex = countBOOK-1;
	
	int i=2;
	while(1==1){
		int CurrentIndex=(EndIndex+StartIndex)/2; //start searching from the mid position
		if(strcmp(hd[CurrentIndex].AUTHOR, AUTHOR) > 0){ 
			PreviousIndex = EndIndex;
			EndIndex = CurrentIndex;
		}else if(strcmp(hd[CurrentIndex].AUTHOR, AUTHOR) < 0){
			PreviousIndex = StartIndex;
			StartIndex = CurrentIndex;
		}else
			{
				SearchBetweenIndex(StartIndex, EndIndex, AUTHOR);
				break;
			}

		if(CurrentIndex == PreviousIndex)
			break;
	
		

	}

}


/////////////////////////////////////////////////////////////////////

void SortAndSearchByAUTHOR(){ // INPUT AUTHOR SEARCH CRITERIA
	system("cls");
	char str[50];
	cout << "Enter the Search Criteria for AUTHOR ";
	gets(str);
	SortByAUTHOR(); // CALL THIS FUNCTION
	ListByAUTHOR(str); // CALLL THIS FUNCTION

}

//***************************************************************
//    	SORT AND SEARCH BY AUTHOR ENDS
//****************************************************************

}
Posted

".... instead search all the records one at a time, from start till the end for its author. I think the improved approach will make the coding a lot shorter than it is now..."

?

If you do not want to sort and search, you can simply loop (for, while) over all your books and just list the books that fit the search criteria.

Also, if you really are using C++, I suggest that you use C++ constructs like std::vector, std::string and all other STL algorithms ... it will make your life easier.

Good luck.
 
Share this answer
 
Comments
Aescleal 19-May-12 5:50am    
I was going to mark you down (ugh, suggesting an explicit loop) until I saw the last sentence. That alone was worth a five!
Hi smrizvi1,
I recommend that you use the STL, because array it's not very...
STL is much more reliable,readable.
It will improve your approach

Here's an example:

For example the illustrating the generic binary search algorithms:
#include <iostream>
#include <cassert>
#include <algorithm>
#include <vector>
using namespace std;

int main()
{
  vector<int> v(5);
  bool found;

  for (int i = 0; i < 5; ++i)
     v[i] = i;

  found = binary_search(v.begin(), v.end(), 3);
  cout << found << " ";

  // Try searching for a value that's not present:
  found = binary_search (v.begin(), v.end(), 9);
  cout << found;

  return 0;
}


About sorting with STL you can read here:
http://create.stephan-brumme.com/stl-sort/[^]

http://www.cplusplus.com/reference/algorithm/sort/[^]

About simple buble sort you can read here:
http://login2win.blogspot.com/2011/06/bubble-sort-in-c.html

or here:
http://www.java2s.com/Tutorial/Cpp/0100__Development/ABubblesort.htm[^]

That's all.

P/S Do not forget to vote if it helped you! :)
 
Share this answer
 
v2
Comments
Aescleal 21-May-12 14:37pm    
The problem here is the questioner doesn't want to find if an element exists (which is what binary search does) but to actually find the book that corresponds to the search parameter.

Really sorting is just a means to an end - it's the sort of thing you do once and then just run find repeatedly over your collection. If you use a presorted collection (e.g. a map) then you don't need to sort anything, although it'll still take O(nlogn) time to complete.
Volynsky Alex 21-May-12 15:56pm    
I just wanted to say the following:
1) For a search, sorting and etc, better use the containers of STL
Because, they provide an opportunity to do different manipulation of data they contain.
2) In addition , work with the STL more safely and beautifully
Arrays is trousseau from C language. No?
Repeat after me...

"When I do a search in C++ and I don't use std::sort and std::find I shall go and punch myself in the head OR, preferably as I don't like pain, I shall rewrite my class so it can be put in a collection and sorted and searched."

Having said that, how can you write a class that enables objects of the class to stick an object in a collection so you can use std::sort and std::find? For simple objects the answer is remarkably, er, simple: You just need a less than operator (for std::sort) and an equality operator (for std::find).

If you use these two you don't need any explicit loops AND the implementations of std::sort (usually uses an O(nlogn) sort at first and then switches to an O(n squared) algorithm when the partitions get small enough) and std::find (usually uses a binary search, O(logn) ) aren't too bad. Time them and see with your data set.

Just to show you how easy this is have a look at the following code. It's not complete but it shows how simple sorting and searching can be if you know how to implement your classes:
C++
#include <string>
#include <ostream>
#include <vector>
#include <algorithm>
    
class book
{
    public:
        book( const std::string &title, const std::string &author )
            : title_( title ), author_( author )
        {
        }

        friend bool operator<( const book &, const book & );
        friend bool operator==( const book &, const book & );
        friend std::ostream &operator<<( std::ostream &, const book & );

    private:
        std::string title_;
        std::string author_;
};

bool operator<( const book &a, const book &b )
{
    return a.author_ < b.author_;
}

bool operator==( const book &a, const book &b )
{
    return a.author_ == b.author_;
}

std::ostream &operator<<( std::ostream &output_to, const book &to_output )
{
    return output_to << "Title:  "   << to_output.title_
                     << "\nAuthor: " << to_output.author_;
}

const book books_you_should_read[] =
{
    book( "The C++ Programming Language", "Stroustrup, Bjarne" ),
    book( "Standard C++ IOStreams and Locales", "Langer, Angela" ),
    book( "Exceptional C++", "Sutter, Herb" ),
    book( "Effective C++", "Myers, Scott" ),
    book( "Accelerated C++", "Koenig, Andrew" )
};

void book_test( std::ostream &output )
{
    std::vector<book> library( std::begin( books_you_should_read ),
                                     std::end( books_you_should_read ) );

    std::sort( std::begin( library ), std::end( library ) );

    auto found = std::find( std::begin( library ),
                            std::end( library ),
                            book( "Anything", "Stroustrup, Bjarne" ) );

    if( found != std::end( library ) )
    {
        output << "Found:\n" << *found << std::endl;
    }
    else
    {
        output << "Couldn't find a book by God" << std::endl;
    }
}

This code isn't a paragon of C++ coding because:

- Everything's inline
- book isn't a useful class - up to you to make it useful
- I haven't used any PIMPs or other compilation firewalls
- It doesn't show all the members you need to write a class that works like a built in type

It's good because:

- It is really simple, all the complexity is managed by the class
- No explicit loops
- Very little conditional code

Oh, and if this is homework:

- Please use this as inspiration in your C++ practice, it ain't perfect but the salient points aren't too bad
- If you copy this and hand it in may you burn in your own hell of personal guilt
- If you copy this and hand it in AND get a good mark then demand your course fee back, your lecturer is crap either by not teaching you the right things or in the wrong order. Either way he's a muppet that's doing you no favours
- Please see the list of books it'd be good for you to read. Start with "Accelerated C++" and go from there

Edited because I hate this editor, it tries to be too effing clever and so was I, so I fixed a bug

PS: From solution 4...

You're starting to do the sort of thing that databases do. You could take a leaf out of their book and construct indexes of all the possible values you could sort and find on. So instead of sorting and finding on the vector of books you'd do it on a collection of book proxy objects, one or more of which would represent the author in the vector of books.

Instead of sorting and searching an array you might as well go the whole hog and use a pair of std::multimaps:
C++
std::multimap<const std::string &, const book &> book_title_name_index;
std::multimap<const std::string &, const book &> author_name_index;
Then hack out each word (sans punctuation) in the title and author of each book sticking the word and the book in the map for each word in the title. So "The Two Towers" by J.R.R.Tolkien would have three entries in the book_title_name_index, one against "The" (you might like to weed out common words that appear frequently), "Two" and "Towers" and one "Tolkien" in the author_name_index as you don't want initials munging up the works.

Then you'll be able to use either the find function on multimap to find a book with the word match, e.g:
C++
auto book_location = book_title_index.find( "Towers" );
if( book_location != end( book_title_index ) )
{
    std::cout << "found:" << *book_location;
}

or use the equal_range function to get any books that match the criteria you set.

So the method is...

- Save the objects you want to work with somewhere easily accessible
- Stick the objects by reference one or more times into one or more multimaps that are keyed by the search parameters you want to use.
- Use find or equal_range to get the objects you're interested in.
 
Share this answer
 
v7
i have seen this version which resembles what i want. can anyone change it to my requirements please?



C++
struct book // declare book class
{
    int no;
    string author; // type name of string
    string book;     // type name of string
    string topic;   // type name of string
    string genre; // type name of string
    book* next;   // type name of string
book()
{
    no=0;
    author=book=topic=genre=" ";
    next=NULL; // next given FALSE value
}



    void setnext(book *t)
  {
    next=t;
  }
    book* getnext()
 {
    return next;
 }
};

    class linklist
    {
    book *start;
    book *current;
    public:
    linklist()
    {
        start=NULL;
        current=NULL;
    }

    void insert(book *tmp)
    {
        if(start==NULL)
        {
            start=tmp;
        }
        else
        {
            current=start;
            while(current->getnext()!=NULL)
            {
                current=current->getnext();
            }
            current->setnext(tmp);
        }
    }


    bool search_no(int value)
        {
            current=start;
            while(current!=NULL)
            {
                if(current->no==value)
                {
                    cout<<current->author<<endl;
                    cout<<current->book<<endl;
                    cout<<current->topic<<endl;
                    cout<<current->genre<<endl;
                    cout<<"------------------------------------------------------------------------"<<endl;
                    return true;
                }
                else
                    current=current->getnext();
            }
            return false;
        }
 
Share this answer
 
Comments
Aescleal 19-May-12 5:48am    
If you want to provide more information for a question, edit the question!

Oh and implementing your own classes for things like lists just sucks. The standard library has collections, why not use them?
I also wanted to know that is it possible search a particular string/char, having more than one word, by just a single word?? I mean If i want to search 'Lord of the rings' and i just input 'rings', is there any way that i get all the books that contain the word 'rings'?
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900