java最小的对象_最小划分对象向量(C)

如果我正确理解您的要求,则“最小分区数”由原始向量中单个值的最大频率给出。因此,您可以创建一个直方图,然后在其中找到最大的条目。 (这与 vector.)的大小呈线性关系,现在创建 m 个矢量(其中 m 是刚刚确定的最大频率),并将 m 个相同的值分别分配给其中一个。保证您可以将其余元素分布在这样就不会在分区中出现重复项。

在 pseudo-code 中,尺寸为 n 的 input-vector v:

初始化一个空的直方图 H

对于 v 中的每个项 x:

将 H [1]加 1,如果尚无此类 bin,则将其 zero-initializing 递增

m←H 中的最大频率

初始化空向量 v1,…,vm

对于每个值 x 均为 H [2]≥0:

因为我←1 到 H [3]:

将 x 附加到 vi

请注意,如果向量中的对象具有确定它们是否等于其唯一数据成员的键,则此方法很好用。但是,如果他们有更多的状态需要保留,但不参与确定平等性,则可以轻松调整此过程以解决这一问题。

初始化一个空的直方图 H

对于 v 中的每个项 x:

如果尚无此类 bin,则将 H [4]加 1,然后 zero-initializing

m←H 中的最大频率

初始化空向量 v1,…,vm

对于 v 中的每个值 x:

我←H [5]

将 x 附加到 vi

将 H [6]减一

这就是(最终有点 over-generalized)实现在 C 14 中的样子。

#include // std::max_element

#include // std::hash, std::equal_to

#include // std::iterator_traits

#include // std::unordered_map

#include // std::vector

template

typename ValueT = typename std::iterator_traits::value_type,

typename ValueHashT = std::hash,

typename ValueEqCmpT = std::equal_to>

decltype(auto)

min_partition(const FwdIterT begin, const FwdIterT end)

{

std::vector<:vector>> partitions {};

std::unordered_map histo {};

for (auto iter = begin; iter != end; ++iter)

histo[*iter]++;

const auto cmpfreq = [](const auto& lhs, const auto& rhs){

return lhs.second < rhs.second;

};

const auto maxbin = std::max_element(histo.cbegin(), histo.cend(), cmpfreq);

partitions.resize(maxbin->second);

for (auto iter = begin; iter != end; ++iter)

partitions.at(histo.at(*iter)-- - 1).push_back(*iter);

return partitions;

}

可以这样使用。

#include // std::cout

#include // std::string

#include // std::begin, std::end

int

main(int argc, char * * argv)

{

using std::begin;

using std::end;

for (int i = 1; i < argc; ++i)

{

const std::string text {argv[i]};

const auto partitions = min_partition(begin(text), end(text));

std::cout << "input: " << text << "\n";

std::cout << "output: " << partitions.size() << " partitions\n\n";

for (auto it1 = begin(partitions); it1 != end(partitions); ++it1)

{

std::cout << "[";

for (auto it2 = begin(*it1); it2 != end(*it1); ++it2)

std::cout << (it2 != begin(*it1) ? ", " : "") << *it2;

std::cout << "]\n";

}

if (i != argc - 1)

std::cout << "\n\n";

}

}

如果给定一些 well-known 字符串作为输入,它将产生以下输出。

input: WEWEREARRESTEDAFTERDADATEDEEREGGS

output: 10 partitions

[W, F, A, T, D, R, E, G, S]

[W, S, T, R, A, D, E, G]

[R, T, A, D, E]

[A, R, D, E]

[R, E]

[E]

[E]

[E]

[E]

[E]

input: ALASDADHADAGLASSSALAD

output: 8 partitions

[H, G, S, L, A, D]

[D, L, S, A]

[L, D, A, S]

[S, D, A]

[A]

[A]

[A]

[A]

input: THEQUICKBROWNFOXJUMPSOVERTHESLEAZYDOG

output: 4 partitions

[Q, I, C, K, B, W, N, F, X, J, U, M, P, V, R, T, H, S, L, E, A, Z, Y, D, O, G]

[T, H, U, R, S, O, E]

[O, E]

[E, O]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值