Hello,

I have an assignment where I have to create a hash table and load 30 part numbers into it- should be a 2-d array...and eventually I have to prompt the user to choose an algorithm and keep track of collisions. But I am starting really small with this and want to start with reading a text file into the array. I am close (i think :confused: ), but I think I may have put the values into my txt file incorrectly. Can anyone offer advice. I will show my code also
the text file just has the numbers 101-110, 301-310 & 501-510 in a list.

//read part numbers from txt file 'parts.txt'

#include <iostream>
#include <fstream>
using namespace std;

int main()
{
    int i;
    int array[41];

    for(i=0; i<5; i++)  //clear array
        array[i] = 0;

    ifstream in("part.txt", ios::in | ios::binary);
    if(!in){
    cout << "cannot open file.\n";
    return 1;
    }

    in.read((char *) &array, sizeof array);  //read block of data

    for(i=0; i<5; i++) //show values read from file
        cout << array[i] << " ";

    in.close();
    return 0;
}

Dani AI

Generated

A common source of trouble here is file format versus read method. ’s note that the file contains things like 101-110 suggests the file uses hyphen ranges, not plain whitespace-separated integers. Reading raw bytes with in.read(..., ios::binary) won’t parse textual ranges. The loop-style extraction used by is fine for plain integers, but hyphenated ranges need tokenizing and expansion first.

A compact way to handle both single numbers and ranges is: read lines, split into tokens, detect a - and expand that range into individual ints, otherwise parse a single value. The function below returns a vector<int> of all part numbers (handles 101-110 and 302 forms):

#include <fstream>
#include <sstream>
#include <string>
#include <vector>

std::vector<int> readParts(const std::string& fname) {
    std::vector<int> parts;
    std::ifstream in(fname);
    std::string line;
    while (std::getline(in, line)) {
        std::istringstream ss(line);
        std::string token;
        while (ss >> token) {
            auto dash = token.find('-');
            if (dash != std::string::npos) {
                int a = std::stoi(token.substr(0, dash));
                int b = std::stoi(token.substr(dash + 1));
                for (int v = a; v <= b; ++v) parts.push_back(v);
            } else {
                parts.push_back(std::stoi(token));
            }
        }
    }
    return parts;
}

Once the flat list of integers exists, placing them into a simple hash table and counting collisions is straightforward. Using separate chaining with vector<vector<int>> makes collision-counting explicit (increment when a bucket already contains entries):

int tableSize = 11; // choose a prime or suitable size
std::vector<std::vector<int>> table(tableSize);
int collisions = 0;
for (int p : parts) {
    int idx = p % tableSize;
    if (!table[idx].empty()) ++collisions;
    table[idx].push_back(p);
}

Notes: validate tokens (catch std::invalid_argument from stoi) and trim punctuation if needed. For classroom exercises that require a fixed 2-D array, allocate [buckets][maxChain], initialize with a sentinel (e.g. -1) and insert into the first free column per row. For production or modern C++ use, std::unordered_map (C++11+) gives a ready hash-table implementation; for learning, the vector-based method above makes collisions and chaining explicit.

Recommended Answers

All 8 Replies

Well for one you declare a array with 41 elements and only seem to need 5. And the lovely thing about fstream is operator overloading so if you want to read in something it's very easy.

#include <iostream>
#include <fstream>

int main()
{
  
  int i = 0;
  int array[5];
  int max_read = 5;
  int amountRead = 0;

  std::ifstream in("part.txt",std::ios::in |std::ios::binary);

  if(!in)
  {
  
    std::cout<<"Could not open file"<<std::endl;
    return 1;
  
  }
  //this is where we are reading in the information into our array
  while(in>>array[amountRead]&& amountRead < max_read)
  {
  
    amountRead++;
  
  }

  for(i = 0; i < 5; i++)
  {
  
    std::cout<<array[i]<<std::endl;
  
  }
  
  std::cin.get();
  
  return 0;  

}

Oh and please use Code Tags

Okay so that was my stupid mistake...I actually have 30 values...so I made the array size 41.

but the changes you made worked great, and I will remember the code tags :o I didn't expect a response so helpful...really appreciate it.

Hey I am not always mean ;).
p.s. Your welcome.

Of course an array is not a hashtable...
There's a hashtable class in the STL, use that.

I know...its just that I am in over my head, and figure if i start simple it might all start to make sense :)

>There's a hashtable class in the STL, use that.
Not according to the standard, though a hashmap is a common extension.

Okay i had a question, how would you do this same exact thing except with a multidimensional array, and if possible convert that array in integers, i can hand the converting, i was having more problems with the multidimensional aspect(I am a student and i have been looking for examples for this, i will post code if you want me to)

commented: zombie master, thread hijacker. homework kiddo -2

Okay i had a question, how would you do this same exact thing except with a multidimensional array, and if possible convert that array in integers, i can hand the converting, i was having more problems with the multidimensional aspect(I am a student and i have been looking for examples for this, i will post code if you want me to)

Please create new thread and any supporting coding. Re-opening years old thread is not good idea to get reply from members.

Thread closed

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.