Second-Hand Market App

 avatarDarin
plain_text
2 months ago
10 kB
6
Indexable
Never
package SecondHandMarketApp;

// tham khảo lời giải của Vũ Chí Bảo, XZ
// tham khảo UserSolution4 với phương thức filter
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class UserSolution {
	// map tag -> danh sách sản phẩm
	Map<String, List<Product>> mapProduct;

	void init(int N) {
		mapProduct = new HashMap<String, List<Product>>();
	}

	void addProduct(int mPrice, int tagNum, char tagName[][]) {
		Product product = new Product(mPrice);
		String[] tags = new String[tagNum];
		for (int i = 0; i < tagNum; i++) {
			tags[i] = string(tagName[i]);
			mapProduct.computeIfAbsent(tags[i], k -> new ArrayList<>()).add(
					product);
		}
		// sort tags để khi ghép tag được chuỗi duy nhất
		// thêm sản phầm vào cả 3 tags
		// thêm dấu - nối để tránh trường hợp ghép trùng
		Arrays.sort(tags);
		for (int i = 0; i < tagNum; i++) {
			for (int j = i + 1; j < tagNum; j++) {
				for (int j2 = j + 1; j2 < tagNum; j2++) {
					mapProduct.computeIfAbsent(
							tags[i] + "-" + tags[j] + "-" + tags[j2],
							k -> new ArrayList<>()).add(product);
				}
			}
		}
	}

	// chú ý kiểm tra sản phẩm trả về thì là null
	// kiểm tra danh sách trả về thì là isEmpty()
	int buyProduct(char tag1[], char tag2[], char tag3[]) {
		String[] tags = { string(tag1), string(tag2), string(tag3) };
		Arrays.sort(tags);
		String tag = tags[0] + "-" + tags[1] + "-" + tags[2];
		// xóa tất cả sản phẩm có isRemoved = true được gắn với tag
		// lấy danh sách sản phẩm gắn với tag trước --> kiểm tra empty()
		// tốt hơn là remove luôn khỏi danh sách của các tag1, tag2, tag3
		mapProduct.computeIfAbsent(tag, k -> new ArrayList<>()).removeIf(
				x -> x.isRemoved); // trả về kiểu boolean
		if (mapProduct.get(tag).isEmpty()) { // !mapProduct.containsKey(tag)
			return -1;
		}
		// mua cái có giá nhỏ nhất trong danh sách tăng dần của HashMap
		Product buyProduct = Collections.min(mapProduct.get(tag),
				(a, b) -> a.price - b.price);
		// Product buyProduct = Collections.max(mapProduct.get(tag), (a, b) -> b.price
		// - a.price);
		buyProduct.isRemoved = true;
		return buyProduct.price;
	}

	// nếu như không xóa sản phẩm khỏi tag1, tag2, tag3 ở buyProduct thì ở phần adjustPrice
	// cần thêm màng lọc chỉ những sản phẩm chưa bị xóa mới được điều chỉnh giá
	void adjustPrice(char tag1[], int changePrice) {
		for (Product product : mapProduct.get(string(tag1))) {
			product.price += changePrice;
			//			if (!product.isRemoved) {
			//				product.price += changePrice;
			//			}
		}
		// version đủ hơn
		// String key = string(tag1);
		// if (!mapProduct.containsKey(key)) {
		// return;
		// }
		// List<Product> proList = mapProduct.get(key);
		// for (Product product : proList) {
		// if (!product.isRemoved) {
		// product.price += changePrice;
		// }
		// }
	}

	String string(char s[]) {
		int n = -1;
		while (s[++n] != 0)
			; // tăng n = độ dài mảng ký tự
		// String temp = new String(s);
		// int n = temp.indexOf('\0');
		return new String(s, 0, n);
		// return String.valueOf(s, 0, n);
	}
	// String charToString(char tagName[]) {
	// StringBuilder res = new StringBuilder();
	// for (int i = 0; tagName[i] != '\0'; i++) {
	// res.append(tagName[i]);
	// }
	// return res.toString();
	// }
}

class Product {
	int price;
	boolean isRemoved;

	public Product(int mPrice) {
		price = mPrice;
		isRemoved = false;
	}
}

//[Problem Description]
//You are required to develop a new second-hand market app.
//The seller can register products to sell and the buyer can purchase products on the app.
//To register, the seller attaches a tag to each product, which can be used for search on the app.
//To buy, the buyer searches the tags of registered products and selects the cheapest one among the searched products.
//The prices of products on the app change according to the tags attached to them. However, those of products registered after the price change, will not be affected.
//Implement a second-hand market app with the features described above.
//Implement each required function by referring to the following API description.
//The following is the description of API to be written in the User Code.
//void init(int N)
//This function is called in the beginning of each test case.
//The number of tags available on the app is N.
//There is no registered product on the app.
//Parameters
//  N : Number of tags available on the app (5 ≤ N ≤ 30 )
//void addProduct(int mPrice, int tagNum, char tagName[][10])
//The seller registers products to sell on the app.
//The price of the registered product is mPrice.
//The number of tags attached to the product is tagNum, each of which has a name tagName[].
//tagName[] are all different from each other.
//tagName[] is a string which consists of lowercase English letters of minimum 3, but no larger than 9, and ends with ‘\0.’
//Parameters
//  mPrice    : Price of the product registered on the app (1 ≤ mPrice ≤ 1,000,000 )
//  tagNum   : Number of tags attached to the registered product on the app ( 3 ≤ tagNum ≤ 5 )
//  tagName[] : Name of the tag attached to the registered product on the app ( 3 ≤ length of tagName[] ≤ 9 )
//int buyProduct(char tag1[], char tag2[], char tag3[])
//The buyer searches products which have all of the three tags on the app.
//Among the searched products, the cheapest one is bought and the price value of the product is returned.
//If there is no such product, -1 is returned.
//Once the buyer purchases a product, it can no longer be seen on the app.
//If two or more products are searched, it is guaranteed that there is only one cheapest product.
//It is guaranteed that the number of products searched on the app is less or equal to 1,000.
//The tags – tag1, tag2, tag3 – are all different from each other.
//The tag is a string which consists of lowercase English letters of minimum 3, but no larger than 9, and ends with ‘\0.’
//Parameters
//tag1 : Name of the first tag ( 3 ≤ length of tag1 ≤ 9 )
//tag2 : Name of the second tag ( 3 ≤ length of tag2 ≤ 9 )
//  tag3 : Name of the third tag ( 3 ≤ length of tag3 ≤ 9 )
//Returns
//  Price of the product purchased by the buyer
//void adjustPrice(char tag1[], int changePrice)
//This function changes by changePrice the prices of all products with “tag1” among the ones on the app.
// 
//If changePrice is a positive number, the prices are increased; if it is a negative number, the prices are decreased.
//If the price of the product is 100 and changePrice is 7, the price changes to 107.
//If the price of the product is 100 and changePrice is -7, the price changes to 93.
//There is no case where the changed price becomes 0 or a negative number.
//If there is no product with “tag1”, nothing happens.
//It is guaranteed that the number of products whose price is to be changed is less or equal to 3,000.
//“tag1” is a string which consists of lowercase English letters of minimum 3, but no larger than 9, and ends with ‘\0.’
//Parameters
//tag1  : Name of the tag ( 3 ≤ length of “tag1” ≤ 9 )
//  changePrice : Price value by which the price of the product with “tag1” changes ( -50,000 ≤ changePrice ≤ 50,000 )


package SecondHandMarketApp;

// KIM ĐỨC
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class UserSolution2 {
	Map<String, List<Product>> mapProduct;

	void init(int N) {
		mapProduct = new HashMap<String, List<Product>>();
	}

	void addProduct(int mPrice, int tagNum, char tagName[][]) {
		Product product = new Product(mPrice);
		String[] tags = new String[tagNum];
		for (int i = 0; i < tagNum; i++) {
			tags[i] = toString(tagName[i]);
			mapProduct.computeIfAbsent(tags[i], k -> new ArrayList<>()).add(
					product);
		}
		Arrays.sort(tags);
		for (int i = 0; i < tagNum; i++) {
			for (int j = i + 1; j < tagNum; j++) {
				for (int j2 = j + 1; j2 < tagNum; j2++) {
					mapProduct.computeIfAbsent(
							tags[i] + "-" + tags[j] + "-" + tags[j2],
							k -> new ArrayList<>()).add(product);
				}
			}
		}
	}

	// trả về giá sản phẩm được mua
	int buyProduct(char tag1[], char tag2[], char tag3[]) {
		String tag = mergeStr(tag1, tag2, tag3);
		if (!mapProduct.containsKey(tag)) { // mapProduct.get(tag).isEmpty()
			return -1;
		}
		List<Product> productList = mapProduct.get(tag);
		Product minProduct = null;
		int boughtPrice = Integer.MAX_VALUE;
		for (Product proX : productList) {
			if (!proX.isRemoved && proX.price < boughtPrice) {
				minProduct = proX;
				boughtPrice = proX.price;
			}
		}
		if (minProduct != null) {
			minProduct.isRemoved = true;
			return boughtPrice;
		} else {
			return -1;
		}
		// mapProduct.get(tag).remove(minProduct);
		// mapProduct.get(toString(tag1)).remove(minProduct);
		// mapProduct.get(toString(tag2)).remove(minProduct);
		// mapProduct.get(toString(tag3)).remove(minProduct);
	}

	void adjustPrice(char tag1[], int changePrice) {
		for (Product product : mapProduct.get(toString(tag1))) {
			product.price += changePrice;
		}
	}

	String toString(char s[]) {
		String temp = new String(s);
		int n = temp.indexOf('\0');
		return new String(s, 0, n);
	}

	String mergeStr(char[] t1, char[] t2, char[] t3) {
		String tag1 = toString(t1), tag2 = toString(t2), tag3 = toString(t3);
		String[] str = { tag1, tag2, tag3 };
		Arrays.sort(str);
		return str[0] + "-" + str[1] + "-" + str[2];
	}

	class Product {
		int price;
		boolean isRemoved;

		public Product(int mPrice) {
			price = mPrice;
			isRemoved = false;
		}
	}

}